2015-05-26 13 views
12

Đây là thiết lập của tôi:Làm thế nào để đăng ký tùy chỉnh UserStore & UserManager trong DI

public class ApplicationUser : IdentityUser<Guid> 
{ 
} 
public class ApplicationRole : IdentityRole<Guid> 
{ 
} 
public class ApplicationUserLogin : IdentityUserLogin<Guid> 
{ 
} 
public class ApplicationUserClaim : IdentityUserClaim<Guid> 
{ 
} 
public class ApplicationRoleClaim : IdentityRoleClaim<Guid> 
{ 
} 

Dưới đây là định nghĩa của UserStore tôi

public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, MyContext, Guid> 
{ 
    public ApplicationUserStore(MyContext context, IdentityErrorDescriber describer = null) 
     : base(context, describer) 
    { 
    } 
} 

Dưới đây là định nghĩa của UserManager tôi

public class ApplicationUserManager : UserManager<ApplicationUser> 
{ 
    public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, 
     IPasswordHasher<ApplicationUser> passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators, 
     IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, 
     IdentityErrorDescriber errors, IEnumerable<IUserTokenProvider<ApplicationUser>> tokenProviders, 
     ILoggerFactory logger, IHttpContextAccessor contextAccessor) 
     : base(
      store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, 
      tokenProviders, logger, contextAccessor) 
    { 
    } 
} 

Đây là định nghĩa của DbContext của tôi:

public class MyContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid> 
{ 
    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 
    } 
} 

Và đây là Startup.cs tôi

public IServiceProvider ConfigureServices(IServiceCollection services) 
    { 
     services.AddMvc(); 

     services.AddEntityFramework() 
      .AddSqlServer() 
      .AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.Get("Data:DbConnection"))); 

     services.AddIdentity<ApplicationUser, ApplicationRole>() 
      .AddEntityFrameworkStores<MyContext, Guid>() 
      .AddUserStore<ApplicationUserStore>() 
      .AddRoleStore<ApplicationRoleStore>() 
      .AddUserManager<ApplicationUserManager>() 
      .AddRoleManager<ApplicationRoleManager>() 
      .AddDefaultTokenProviders(); 

     var builder = new ContainerBuilder(); 
     builder.Populate(services); 
     var container = builder.Build(); 
     return container.Resolve<IServiceProvider>(); 
    } 

Các phụ thuộc của constructor này sẽ làm việc:

public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager) 

Cái này sẽ không:

public AccountController(ApplicationUserManager userManager, SignInManager<ApplicationUser> signInManager) 

Bất cứ ai cũng có một ý tưởng về những gì tôi đang làm sai?

+0

nào NuGet phiên bản gói bạn đã tham khảo cho Microsoft.AspNet.Identity.Core? Tôi đang cố gắng để tạo ra một CustomUsermanager, nhưng khi tôi kế thừa từ UserManager constructor yêu cầu 9 tham số, nhưng constructor của bạn mất 10 đối số ..? Tôi đang sử dụng AspDotNetCoreFullFramework. – Legends

+0

'IUserTokenProvider' không được nhận dạng! – Legends

Trả lời

8

DI nói chung là dành cho phát triển theo hướng giao diện; .AddUserManager<ApplicationUserManager>() chỉ định triển khai UserManager<>, không phải giao diện dịch vụ. Điều đó có nghĩa là nó vẫn mong bạn nhận được UserManager<ApplicationUser> và chỉ sử dụng nó theo cách đó; nó sẽ cung cấp cho bạn ApplicationUserManager.

Tôi giả sử rằng bạn có các phương thức bổ sung mà bạn muốn sử dụng trên ApplicationUserManager của mình. Nếu không,chỉ cần sử dụng hàm tạo phụ thuộc theo cách nó hoạt động và tận hưởng sự phát triển theo hướng giao diện. Nếu vậy, bạn có 3 lựa chọn:

  1. Sử dụng phần mở rộng thông qua thành phần chứ không phải là thừa kế. Thay vì kế thừa từ UserManager<>, hãy viết ApplicationUserManager làm lớp bao bọc; bạn có thể bao gồm nó trong hàm tạo. Điều này sẽ cung cấp cho bạn tất cả các chức năng bạn cần bên trong của ApplicationUserManager.

  2. Tự thêm nó vào chính khuôn khổ DI. Đây không phải là khó khăn như nó âm thanh, kể từ khi UserManager<> không có thực trạng bản thân:

    services.AddScoped<ApplicationUserManager>(); 
    

    Những bất lợi ở đây là bạn sẽ thực sự có hai UserManager<> đối tượng cho phạm vi của người sử dụng; có thể có một số kết quả không hiệu quả. Từ trạng thái của mã hiện tại, tôi không nghĩ là vậy.

  3. Viết làm phương thức mở rộng. Nếu bạn có một số phụ thuộc và không chỉ là chức năng cơ bản của UserManager<>, điều này có thể thực sự phức tạp.

+0

Chính xác, tôi thực sự sẽ sửa lỗi này 'sớm' https://github.com/aspnet/Identity/issues/493 –

3

Tôi hiện đang sử dụng ASP.NET Core 1.1 và hành vi này đã được khắc phục.

tôi có thể dễ dàng thực hiện UserManager của riêng tôi và UserStore, sau đó bootstrap ứng dụng như sau:

// identity models 
services 
    .AddIdentity<ApplicationUser, ApplicationRole>() 
    .AddEntityFrameworkStores<ApplicationDbContext, Guid>() 
    .AddUserManager<ApplicationUserManager>() 
    .AddUserStore<ApplicationUserStore>() 
    .AddDefaultTokenProviders(); 

và tiêm cả UserManager và UserStore vào điều khiển của tôi, mà không cần bất kỳ vấn đề:

public AccountController(
    IIdentityServerInteractionService interaction, 
    IClientStore clientStore, 
    IHttpContextAccessor httpContextAccessor, 
    ApplicationUserManager userManager, 
    SignInManager<ApplicationUser> signInManager, 
    IEmailSender emailSender, 
    ISmsSender smsSender, 
    ILoggerFactory loggerFactory) 
{ 
    _interaction = interaction; 
    _userManager = userManager; 
    _signInManager = signInManager; 
    _emailSender = emailSender; 
    _smsSender = smsSender; 
    _logger = loggerFactory.CreateLogger<AccountController>(); 
    _account = new AccountService(_interaction, httpContextAccessor, clientStore); 
} 
+0

Cảm ơn bạn đã trả lời - hãy để tôi đi đúng hướng! Hoạt động như mong đợi. – sjkm

Các vấn đề liên quan