If I surf to http://localhost:58472/Account/Register
I've this exception
System.InvalidOperationException:
The current type,IUserStore<ApplicationUser>
, is an interface and cannot be constructed. Are you missing a type mapping?
Here is my code:
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;
}
}
and here is the code into the controller:
[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();
}
}
So you can see if you read my code, I've nothing changed to the original code when you create a new MVC project, but I've got the error above. What did I wrong?
I've well made a new controller named ProfileController
with the same code as in my second code block but without the ApplicationSignInManager
because I don't need that.
I also use an Unity container to register and manage the services. Here is the code:
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));
}
}
If I uncomment the line in code above, there aren't any difference when I run the site.
Update:
By a comment by @Jay I've added this code in the Unity manager.
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
Now I've got this exception:
System.InvalidOperationException
: The current type,System.Data.Common.DbConnection
, is an abstract class and cannot be constructed. Are you missing a type mapping?
Here is some information from the stack trace:
InvalidOperationException
An error occurred when trying to create a controller of type
AccountController
. Make sure that the controller has a parameterless public constructor.
Yes, I've got a paramaterless public constructor.
ResolutionFailedException
Resolution of the dependency failed, type =
"AccountController"
, name ="(none)"
.
So I've added this line in the Unity manager:
container.RegisterType<IDbConnection, DbConnection>();
But I've still have the same exception.
The current type,
System.Data.Common.DbConnection
...
Update:
By a comment by @RandyLevy I've tried this, helping by this question Configure Unity DI for ASP.NET Identity:
Adding this to the 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;
// }
//}
Adding this into 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);
But I've got this error (no run time exception) on the line with the comment:
The type
RoleStore<IdentityRole>
cannot be used as type parameterTTo
in the generic type or method below:UnityContainerExtensions.RegisterType<TFrom, TTo> (IUnityContainer, params InjectionMember[])
There is no implicit reference conversion from
RoleStore<IdentityRole>
toIRoleStore<IdentityRole>
.
Finally I've found a solution for my problem. I've add this code into the Unity manager.
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());
Update for H. Pauwelyn answer. The original problem for this is that Unity tries to call the constructor with two parameters.
public AccountController(
ApplicationUserManager userManager,
ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
}
The following line will tell Unity to call the parameterless constructor instead and won't need anything else. This worked for me.
container.RegisterType<AccountController>(new InjectionConstructor());
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