5

Nếu tôi lướt đến http://localhost:58472/Account/Register Tôi đã ngoại lệ nàyCác loại hiện nay, IUserStore <ApplicationUser> và DbConnection, tương ứng một giao diện và lớp trừu tượng và không thể được xây dựng

System.InvalidOperationException: Các loại hiện nay, IUserStore<ApplicationUser>, là một giao diện và không thể được xây dựng. Bạn đang thiếu một ánh xạ kiểu?

Đây là mã của tôi:

public class ApplicationUserManager : UserManager<ApplicationUser> 
{ 
    public ApplicationUserManager(IUserStore<ApplicationUser> store) 
     : base(store) 
    { } 

    public static ApplicationUserManager Create(
     IdentityFactoryOptions<ApplicationUserManager> options, 
     IOwinContext context) 
    { 
     var manager = new ApplicationUserManager(
      new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()) 
     ); 

     // other code 
     return manager; 
    } 
} 

và đây là mã vào bộ điều khiển:

[Authorize] 
public class AccountController : Controller 
{ 
    private ApplicationSignInManager _signInManager; 
    private ApplicationUserManager _userManager; 

    public AccountController() 
    { 
    } 

    public AccountController(
     ApplicationUserManager userManager, 
     ApplicationSignInManager signInManager) 
    { 
     UserManager = userManager; 
     SignInManager = signInManager; 
    } 

    public ApplicationSignInManager SignInManager 
    { 
     get 
     { 
      return _signInManager ?? 
       HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); 
     } 
     private set 
     { 
      _signInManager = value; 
     } 
    } 

    public ApplicationUserManager UserManager 
    { 
     get 
     { 
      return _userManager ?? 
       HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
     } 
     private set 
     { 
      _userManager = value; 
     } 
    } 

    [HttpGet] 
    [AllowAnonymous] 
    public ActionResult Login(string returnUrl) 
    { 
     ViewBag.ReturnUrl = returnUrl; 
     return View(); 
    } 
} 

Vì vậy, bạn có thể thấy nếu bạn đọc mã của tôi, tôi đã không có gì thay đổi mã gốc khi bạn tạo một dự án MVC mới, nhưng tôi đã có lỗi ở trên. Tôi đã làm gì sai?

Tôi cũng đã tạo bộ điều khiển mới có tên ProfileController với cùng mã như trong khối mã thứ hai của tôi nhưng không có số ApplicationSignInManager vì tôi không cần điều đó.

Tôi cũng sử dụng vùng chứa Unity để đăng ký và quản lý dịch vụ. Đây là mã:

public static class UnityConfig 
{ 
    public static void RegisterComponents() 
    { 
     var container = new UnityContainer(); 

     container.RegisterType<IGenericRepo<Category>, GenericRepo<Category>>(); 
     container.RegisterType<ICategoryService, CategoryService>(); 
     //container.RegisterType<IUser, ApplicationUser>(); 

     DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 
    } 
} 

Nếu tôi bỏ ghi chú dòng mã ở trên, không có bất kỳ sự khác biệt nào khi tôi chạy trang web.


Cập nhật:

Bằng một bình luận bởi @ Jay Tôi đã thêm mã này trong quản lý Unity.

container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(); 

Bây giờ tôi đã có ngoại lệ này:

System.InvalidOperationException: Các loại hiện nay, System.Data.Common.DbConnection, là một lớp trừu tượng và không thể được xây dựng. Bạn đang thiếu một ánh xạ kiểu?

Dưới đây là một số thông tin từ stack trace:

  1. InvalidOperationException

    Một lỗi xảy ra khi cố gắng để tạo ra một bộ điều khiển kiểu AccountController. Đảm bảo rằng bộ điều khiển có một hàm tạo công khai không tham số.

    Vâng, tôi có một nhà xây dựng công khai không cần thiết.

  2. ResolutionFailedException

    Nghị quyết của sự phụ thuộc thất bại, type = "AccountController", name = "(none)".

Vì vậy, tôi đã thêm dòng này trong bộ quản lý Unity:

container.RegisterType<IDbConnection, DbConnection>(); 

Nhưng tôi vẫn có ngoại lệ tương tự.

Các loại hiện nay, System.Data.Common.DbConnection ...


Cập nhật:

Bằng một lời nhận xét của @RandyLevy tôi đã cố gắng này, giúp bởi câu hỏi này Configure Unity DI for ASP.NET Identity:

  1. Thêm này đến AccountController:

    // two fields added 
    private readonly UserManager<ApplicationUser> _userManager; 
    private readonly RoleManager<IdentityRole> _roleManager; 
    
    // constructor added 
    public AccountController(
        IUserStore<ApplicationUser> userStore, 
        IRoleStore<IdentityRole> roleStore, 
        ApplicationSignInManager signInManager) 
    { 
        _userManager = new UserManager<ApplicationUser>(userStore); 
        _roleManager = new RoleManager<IdentityRole>(roleStore); 
        SignInManager = signInManager; // I need this 
    } 
    
    public ApplicationSignInManager SignInManager // I need this 
    { 
        get 
        { 
         return _signInManager ?? 
          HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); 
        } 
        private set 
        { 
         _signInManager = value; 
        } 
    } 
    
    public UserManager<ApplicationUser> UserManager // replace by other property 
                   // type of ApplicationUserManager 
    { 
        get 
        { 
         return _userManager ?? 
          HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
        } 
        //private set // comment this because _usermanager is readonly. 
        //{ 
        // _userManager = value; 
        //} 
    } 
    
    //public ApplicationUserManager UserManager // replaced by the property type of 
    //           // UserManager<ApplicationUser> 
    //{ 
    // get 
    // { 
    //  return _userManager ?? 
    //   HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
    // } 
    // private set 
    // { 
    //  _userManager = value; 
    // } 
    //} 
    
  2. Thêm này vào UnityManager:

    InjectionConstructor accountInjectionConstructor = 
        new InjectionConstructor(new ApplicationDbContext()); 
    
    container.RegisterType<AccountController>(); 
    container.RegisterType<IController, Controller>(); 
    
    container.RegisterType 
        <IRoleStore<IdentityRole>, RoleStore<IdentityRole>> 
        (accountInjectionConstructor); // on this line 
    
    container.RegisterType 
        <IUserStore<ApplicationUser>, UserStore<ApplicationUser>> 
        (accountInjectionConstructor); 
    

Nhưng tôi đã có lỗi này (không có thời gian chạy ngoại lệ) trên phù hợp với nhận xét:

Không thể sử dụng loại RoleStore<IdentityRole> làm thông số loại TTo trong loại chung hoặc meth od dưới đây:

UnityContainerExtensions.RegisterType<TFrom, TTo> 
    (IUnityContainer, params InjectionMember[]) 

Không có chuyển đổi tài liệu tham khảo ngầm RoleStore<IdentityRole>-IRoleStore<IdentityRole>.

+2

bạn có thiếu loại đăng ký cho IUserStore không? – Jay

+1

https://stackoverflow.com/questions/21927785/configure-unity-di-for-asp-net-identity có thể hữu ích. –

+0

@Jay: Cảm ơn, vì gợi ý nhưng bây giờ tôi đã là một ngoại lệ khác. Thêm thông tin trong câu hỏi của tôi. –

Trả lời

13

Cuối cùng tôi đã tìm được giải pháp cho vấn đề của mình. Tôi đã thêm mã này vào trình quản lý Unity.

container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager()); 
container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager()); 
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager()); 
container.RegisterType<AccountController>(new InjectionConstructor()); 
+1

Tôi chỉ bắt đầu nhận được lỗi mà OP đã nhận được sau khi tôi cài đặt Unity. Dường như có liên quan đến trình phân giải phụ thuộc của Unity không hoạt động với chức năng Identity gốc. Đăng ký các loại này đã sửa nó. – JARRRRG

2

Cập nhật cho H. Pauwelyn trả lời. Vấn đề ban đầu cho điều này là Unity cố gắng gọi hàm tạo với hai tham số.

public AccountController(
    ApplicationUserManager userManager, 
    ApplicationSignInManager signInManager) 
{ 
    UserManager = userManager; 
    SignInManager = signInManager; 
} 

Dòng sau sẽ yêu cầu Unity gọi hàm tạo tham số thay thế và không cần bất kỳ thứ gì khác. Điều này làm việc cho tôi.

container.RegisterType<AccountController>(new InjectionConstructor()); 
Các vấn đề liên quan