Unity接口未将IUserStore [Models.ApplicationUser]解析为Class,但使用InjectionConstructor解析

时间:2017-08-01 04:44:11

标签: c# asp.net-mvc dependency-injection inversion-of-control unity-container

当我尝试调用Accounts控制器时,我收到此错误,

  

[InvalidOperationException:当前类型Microsoft.AspNet.Identity.IUserStore`1 [Proj1.Web.Models.ApplicationUser]是一个接口,无法构造。你错过了类型映射吗?]

但在搜索之后,我得到了它的工作;

container.RegisterType<AccountController>(new InjectionConstructor());

但为什么会出现这个错误?

帐户控制器的参数少于构造函数,

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

然后ApplicationUserManager具有以下参数less constructor。

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

所以依赖是IUserStore。

现在,作为我的标准做法,我会做以下事情:

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

但相反,我们正在做,哪种感觉像魔术

container.RegisterType<AccountController>(new InjectionConstructor());

以上行是什么意思?

1 个答案:

答案 0 :(得分:3)

InvalidOperationException的原因是Unity默认情况下将选择具有最多参数的构造函数作为用于实例化对象的构造函数。

在这种情况下将是

public AccountController(ApplicationUserManager userManager,
                         ApplicationSignInManager signInManager)

取决于ApplicationUserManager,这取决于IUserStore<ApplicationUser>的实现。似乎Unity中没有注册将IUserStore映射到具体类,因此Unity会抛出异常。

原因

container.RegisterType<AccountController>(new InjectionConstructor());

的工作原理是这个带有“空”InjectionConstructor的注册告诉Unity在实例化AccountController时使用无参数构造函数:public AccountController()。这样可以正常工作,因为没有其他依赖项可以解决。

这是否是您想要的将取决于您的实现,但通常您希望明确地将依赖项注入构造函数而不使用无参数构造函数。

另请注意,在

的情况下
container.RegisterType<IUserStore<ApplicationUser>,UserStore<ApplicationUser>>(); 

您也可以使用开放式泛型注册,以便在不注册所有可能类型的T的情况下解析任何IUserStore<T>

container.RegisterType(typeof(IUserStore<>), typeof(UserStore<>));
// Will resolve both concrete types
var userStore1 = container.Resolve<IUserStore<ApplicationUser>>();
var userStore2 = container.Resolve<IUserStore<OtherApplicationUser>>();