IUserStore[Models.ApplicationUser] 未由 Unity Interface 解析为 Class,而是通过 InjectionConstructor 解析

IUserStore[Models.ApplicationUser] is not resolved by Unity Interface to Class, but resolved with InjectionConstructor

当我试图调用账户控制器时,我收到了这个错误,

[InvalidOperationException: The current type, Microsoft.AspNet.Identity.IUserStore`1[Proj1.Web.Models.ApplicationUser], is an interface and cannot be constructed. Are you missing a type mapping?]

但是在搜索之后我通过 ;

让它工作了
container.RegisterType<AccountController>(new InjectionConstructor());

但是为什么首先出现这个错误?

帐户控制器有一个参数较少的构造函数,

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

然后 ApplicationUserManager 具有以下无参数构造函数。

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

所以依赖是IUserStore。

现在,作为我的标准做法,我将执行以下操作:

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

但我们正在做,这感觉就像魔术

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

上面一行是什么意思?

InvalidOperationException的原因是Unity默认会select参数最多的构造函数作为实例化对象的构造函数。

在这种情况下会是

public AccountController(ApplicationUserManager userManager,
                         ApplicationSignInManager signInManager)

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

原因

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

有效的是,使用 "empty" InjectionConstructor 的注册告诉 Unity 在实例化 AccountController 时使用无参数构造函数:public AccountController()。这工作正常,因为没有额外的依赖关系需要解决。

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

另请注意,在

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

您还可以使用开放泛型进行注册,这样任何 IUserStore<T> 都可以在不注册所有可能的 T 类型的情况下得到解析。

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