When I am trying to invoke Accounts controller, I am getting this error back,
[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?]
But after searching through I got it working by ;
container.RegisterType<AccountController>(new InjectionConstructor());
But why this error in first place?
Account controller has a parameter less constructor ,
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
{
UserManager = userManager;
SignInManager = signInManager;
}
and then ApplicationUserManager has following parameter less constructor.
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
So the dependency is IUserStore.
Now, as my standard practice , I would be doing something like following:
container.RegisterType<IUserStore<ApplicationUser>,UserStore<ApplicationUser>>();
But instead we are doing , which kind of feels like magic
container.RegisterType<AccountController>(new InjectionConstructor());
What does above line means?
The reason for the InvalidOperationException
is that Unity, by default, will select the constructor with the most number of arguments as the constructor to use to instantiate the object.
In this case that would be
public AccountController(ApplicationUserManager userManager,
ApplicationSignInManager signInManager)
which depends on ApplicationUserManager
which depends on an implementation of IUserStore<ApplicationUser>
. It seems that there is no registration in Unity mapping an IUserStore
to a concrete class so Unity throws an exception.
The reason why
container.RegisterType<AccountController>(new InjectionConstructor());
works is that this registration with an "empty" InjectionConstructor
tells Unity to use the parameterless constructor: public AccountController()
when instantiating the AccountController. This works fine since there are no additional dependencies to resolve.
Whether this is what you want or not will depend on your implementation but usually you want to explicitly inject the dependencies into the constructor and not use the parameterless constructor.
Also note that in the case of
container.RegisterType<IUserStore<ApplicationUser>,UserStore<ApplicationUser>>();
you could also register using open generics so that any IUserStore<T>
can be resolved without registering all of the possible types of T.
container.RegisterType(typeof(IUserStore<>), typeof(UserStore<>));
// Will resolve both concrete types
var userStore1 = container.Resolve<IUserStore<ApplicationUser>>();
var userStore2 = container.Resolve<IUserStore<OtherApplicationUser>>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With