From 5ebe61562e0016f5c01e7ac756bd3ef5f20e7ef2 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Wed, 20 Mar 2019 13:37:33 +0300 Subject: [PATCH] Added AppUser to the MVC template --- .../Users/AppUser.cs | 53 +++++++++++++++++ .../MyProjectNameMigrationsDbContext.cs | 12 ++++ .../MyProjectNameDbContext.cs | 21 +++++++ .../MyProjectNameDbContextFactory.cs | 29 --------- ...ectNameDbContextModelCreatingExtensions.cs | 29 +++++---- .../MongoDb/MyProjectNameMongoDbContext.cs | 16 ++++- ...ame.MyProjectName.Application.Tests.csproj | 2 +- .../MyProjectNameApplicationTestModule.cs | 4 +- .../Samples/SampleTest.cs | 26 -------- .../Samples/SampleTests.cs | 59 +++++++++++++++++++ 10 files changed, 176 insertions(+), 75 deletions(-) create mode 100644 templates/mvc/src/MyCompanyName.MyProjectName.Domain/Users/AppUser.cs delete mode 100644 templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextFactory.cs delete mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTest.cs create mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTests.cs diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Domain/Users/AppUser.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Domain/Users/AppUser.cs new file mode 100644 index 0000000000..587c9d9440 --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Domain/Users/AppUser.cs @@ -0,0 +1,53 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.Users; + +namespace MyCompanyName.MyProjectName.Users +{ + /* This entity shares the same table/collection ("AbpUsers" by default) with the + * IdentityUser entity of the Identity module. + * + * - You can define your custom properties into this class. + * - You never create or delete this entity, becase it is Identity module's job. + * - You can query users from database with this entity. + * - You can update values of your custom properties. + */ + public class AppUser : FullAuditedAggregateRoot, IUser + { + #region Base properties + + /* These properties are shared with the IdentityUser entity of the Identity module. + * Do not change these properties through this class. Instead, use Identity module + * services (like IdentityUserManager) to change them. + * So, this properties are designed as read only! + */ + + public virtual Guid? TenantId { get; private set; } + + public virtual string UserName { get; private set; } + + public virtual string Name { get; private set; } + + public virtual string Surname { get; private set; } + + public virtual string Email { get; private set; } + + public virtual bool EmailConfirmed { get; private set; } + + public virtual string PhoneNumber { get; private set; } + + public virtual bool PhoneNumberConfirmed { get; private set; } + + #endregion + + /* Add your own properties here. Example: + * + * public virtual string MyProperty { get; set; } + */ + + private AppUser() + { + + } + } +} diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/MyProjectNameMigrationsDbContext.cs b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/MyProjectNameMigrationsDbContext.cs index 4d8e7bd10f..5fe35526b0 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/MyProjectNameMigrationsDbContext.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/MyProjectNameMigrationsDbContext.cs @@ -2,6 +2,7 @@ using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.BackgroundJobs.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Identity; using Volo.Abp.Identity.EntityFrameworkCore; using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.SettingManagement.EntityFrameworkCore; @@ -20,12 +21,23 @@ namespace MyCompanyName.MyProjectName.EntityFrameworkCore { base.OnModelCreating(builder); + /* Include modules to your migration db context */ + builder.ConfigurePermissionManagement(); builder.ConfigureSettingManagement(); builder.ConfigureBackgroundJobs(); builder.ConfigureAuditLogging(); builder.ConfigureIdentity(); + /* Configure customizations for entities from the modules included */ + + builder.Entity(b => + { + b.ConfigureCustomUserProperties(); + }); + + /* Configure your own tables/entities inside the ConfigureMyProjectName method */ + builder.ConfigureMyProjectName(); } } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs index fb4008aff4..5b40bb037a 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs @@ -1,12 +1,17 @@ using Microsoft.EntityFrameworkCore; +using MyCompanyName.MyProjectName.Users; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Modeling; +using Volo.Abp.Users.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.EntityFrameworkCore { [ConnectionStringName("Default")] public class MyProjectNameDbContext : AbpDbContext { + public DbSet Users { get; set; } + public MyProjectNameDbContext(DbContextOptions options) : base(options) { @@ -17,6 +22,22 @@ namespace MyCompanyName.MyProjectName.EntityFrameworkCore { base.OnModelCreating(builder); + /* Configure your shared tables (with included modules) here */ + + builder.Entity(b => + { + b.ToTable("AbpUsers"); //Sharing the same table "AbpUsers" with the IdentityUser + + b.ConfigureFullAudited(); + b.ConfigureExtraProperties(); + b.ConfigureConcurrencyStamp(); + b.ConfigureAbpUser(); + + b.ConfigureCustomUserProperties(); + }); + + /* Configure your own tables/entities inside the ConfigureMyProjectName method */ + builder.ConfigureMyProjectName(); } } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextFactory.cs b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextFactory.cs deleted file mode 100644 index c878f12fd5..0000000000 --- a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextFactory.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.IO; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; -using Microsoft.Extensions.Configuration; - -namespace MyCompanyName.MyProjectName.EntityFrameworkCore -{ - public class MyProjectNameDbContextFactory : IDesignTimeDbContextFactory - { - public MyProjectNameDbContext CreateDbContext(string[] args) - { - var configuration = BuildConfiguration(); - - var builder = new DbContextOptionsBuilder() - .UseSqlServer(configuration.GetConnectionString("Default")); - - return new MyProjectNameDbContext(builder.Options); - } - - private static IConfigurationRoot BuildConfiguration() - { - var builder = new ConfigurationBuilder() - .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../MyCompanyName.MyProjectName.Web/")) - .AddJsonFile("appsettings.json", optional: false); - - return builder.Build(); - } - } -} diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextModelCreatingExtensions.cs b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextModelCreatingExtensions.cs index 719d8f2c1e..f345d756db 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextModelCreatingExtensions.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextModelCreatingExtensions.cs @@ -1,5 +1,9 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using MyCompanyName.MyProjectName.Users; using Volo.Abp; +using Volo.Abp.Identity; +using Volo.Abp.Users; namespace MyCompanyName.MyProjectName.EntityFrameworkCore { @@ -12,23 +16,18 @@ namespace MyCompanyName.MyProjectName.EntityFrameworkCore var tablePrefix = MyProjectNameConsts.DefaultDbTablePrefix; var schema = MyProjectNameConsts.DefaultDbSchema; - /* Configure all entities here. Example: + //builder.Entity(b => + //{ + // b.ToTable(tablePrefix + "YourEntities", schema); - builder.Entity(b => - { - //Configure table & schema name - //b.ToTable(tablePrefix + "Questions", schema); - - //Properties - //b.Property(q => q.Title).IsRequired().HasMaxLength(QuestionConsts.MaxTitleLength); - - //Configure relations - //b.HasMany(question => question.Tags).WithOne().HasForeignKey(qt => qt.QuestionId); + // //... + //}); + } - //Configure indexes - //b.HasIndex(q => q.CreationTime); - }); - */ + public static void ConfigureCustomUserProperties(this EntityTypeBuilder b) + where TUser: class, IUser + { + //b.Property(nameof(AppUser.MyProperty))... } } } \ No newline at end of file diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.MongoDB/MongoDb/MyProjectNameMongoDbContext.cs b/templates/mvc/src/MyCompanyName.MyProjectName.MongoDB/MongoDb/MyProjectNameMongoDbContext.cs index 19c21ca038..95a041809f 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.MongoDB/MongoDb/MyProjectNameMongoDbContext.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.MongoDB/MongoDb/MyProjectNameMongoDbContext.cs @@ -1,4 +1,6 @@ -using Volo.Abp.Data; +using MongoDB.Driver; +using MyCompanyName.MyProjectName.Users; +using Volo.Abp.Data; using Volo.Abp.MongoDB; namespace MyCompanyName.MyProjectName.MongoDb @@ -6,6 +8,16 @@ namespace MyCompanyName.MyProjectName.MongoDb [ConnectionStringName("Default")] public class MyProjectNameMongoDbContext : AbpMongoDbContext { - + public IMongoCollection Users => Collection(); + + protected override void CreateModel(IMongoModelBuilder modelBuilder) + { + base.CreateModel(modelBuilder); + + modelBuilder.Entity(b => + { + b.CollectionName = "AbpUsers"; //Sharing the same collection "AbpUsers" with the IdentityUser + }); + } } } diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj index e9b614f5e8..808ee9f1fe 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj @@ -9,9 +9,9 @@ - + diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestModule.cs b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestModule.cs index 145710c15b..d44dc0bb5a 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestModule.cs +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestModule.cs @@ -53,11 +53,11 @@ namespace MyCompanyName.MyProjectName var connection = new SqliteConnection("Data Source=:memory:"); connection.Open(); - var options = new DbContextOptionsBuilder() + var options = new DbContextOptionsBuilder() .UseSqlite(connection) .Options; - using (var context = new MyProjectNameDbContext(options)) + using (var context = new MyProjectNameMigrationsDbContext(options)) { context.GetService().CreateTables(); } diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTest.cs b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTest.cs deleted file mode 100644 index e0f87e86c8..0000000000 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTest.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Shouldly; -using Volo.Abp.Identity; -using Xunit; - -namespace MyCompanyName.MyProjectName.Samples -{ - public class SampleTest : MyProjectNameApplicationTestBase - { - private readonly IIdentityUserAppService _userAppService; - - public SampleTest() - { - _userAppService = ServiceProvider.GetRequiredService(); - } - - [Fact] - public async Task Initial_Data_Should_Contain_Admin_User() - { - var result = await _userAppService.GetListAsync(new GetIdentityUsersInput()); - result.TotalCount.ShouldBeGreaterThan(0); - result.Items.ShouldContain(u => u.UserName == "admin"); - } - } -} diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTests.cs b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTests.cs new file mode 100644 index 0000000000..3baff2826f --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTests.cs @@ -0,0 +1,59 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using MyCompanyName.MyProjectName.Users; +using Shouldly; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Identity; +using Volo.Abp.Uow; +using Xunit; + +namespace MyCompanyName.MyProjectName.Samples +{ + public class SampleTests : MyProjectNameApplicationTestBase + { + private readonly IIdentityUserAppService _userAppService; + private readonly IRepository _appUserRepository; + private readonly IUnitOfWorkManager _unitOfWorkManager; + + public SampleTests() + { + _userAppService = ServiceProvider.GetRequiredService(); + _appUserRepository = ServiceProvider.GetRequiredService>(); + _unitOfWorkManager = ServiceProvider.GetRequiredService(); + } + + [Fact] + public async Task Initial_Data_Should_Contain_Admin_User() + { + //Act + var result = await _userAppService.GetListAsync(new GetIdentityUsersInput()); + + //Assert + result.TotalCount.ShouldBeGreaterThan(0); + result.Items.ShouldContain(u => u.UserName == "admin"); + } + + [Fact] + public async Task Should_Query_AppUser() + { + /* Need to manually start Unit Of Work because + * FirstOrDefaultAsync should be executed while db connection / context is available. + */ + using (var uow = _unitOfWorkManager.Begin()) + { + //Act + var adminUser = await _appUserRepository + .Where(u => u.UserName == "admin") + .FirstOrDefaultAsync(); + + //Assert + adminUser.ShouldNotBeNull(); + + await uow.CompleteAsync(); + } + } + } +}