当前类型IUserStore<ApplicationUser>和DbConnection分别是接口和抽象class,无法构造
The current types, IUserStore<ApplicationUser> and DbConnection, are respectively an interface and abstract class and cannot be constructed
如果我上网 http://localhost:58472/Account/Register
我有这个例外
System.InvalidOperationException:
The current type, IUserStore<ApplicationUser>
, is an interface and cannot be constructed. Are you missing a type mapping?
这是我的代码:
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;
}
}
这是控制器中的代码:
[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();
}
}
所以你看了我的代码就知道了,我在新建MVC项目的时候没有对原来的代码做任何改动,但是出现了上面的错误。我做错了什么?
我很好地制作了一个名为 ProfileController
的新控制器,其代码与我的第二个代码块中的代码相同,但没有 ApplicationSignInManager
,因为我不需要那个。
我还使用 Unity 容器来注册和管理服务。这是代码:
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));
}
}
如果我取消注释上面代码中的行,那么当我 运行 站点时没有任何区别。
更新:
根据@Jay 的评论,我在 Unity 管理器中添加了这段代码。
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
现在我遇到了这个异常:
System.InvalidOperationException
: The current type, System.Data.Common.DbConnection
, is an abstract class and cannot be constructed. Are you missing a type mapping?
这是堆栈跟踪中的一些信息:
InvalidOperationException
An error occurred when trying to create a controller of type AccountController
. Make sure that the controller has a parameterless public constructor.
是的,我有一个无参数的 public 构造函数。
ResolutionFailedException
Resolution of the dependency failed, type = "AccountController"
, name = "(none)"
.
所以我在 Unity 管理器中添加了这一行:
container.RegisterType<IDbConnection, DbConnection>();
但我仍然有同样的异常。
The current type, System.Data.Common.DbConnection
...
更新:
根据@RandyLevy 的评论,我试过了,帮助解决了这个问题 Configure Unity DI for ASP.NET Identity:
将此添加到 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;
// }
//}
将其添加到 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);
但是我在评论的行上遇到了这个错误(没有 运行 时间异常):
The type RoleStore<IdentityRole>
cannot be used as type parameter TTo
in the generic type or method below:
UnityContainerExtensions.RegisterType<TFrom, TTo>
(IUnityContainer, params InjectionMember[])
There is no implicit reference conversion from RoleStore<IdentityRole>
to IRoleStore<IdentityRole>
.
我终于找到了解决问题的方法。我已将此代码添加到 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());
更新 H. Pauwelyn 的回答。最初的问题是 Unity 试图用两个参数调用构造函数。
public AccountController(
ApplicationUserManager userManager,
ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
}
下一行将告诉 Unity 改为调用无参数构造函数,不需要任何其他内容。这对我有用。
container.RegisterType<AccountController>(new InjectionConstructor());
或者,可以使用 [ApplicationUserManager userManager,ApplicationSignInManager signInManager] 从 AccountController 中删除构造函数,只留下一个无参数的构造函数(或一个具有统一解析依赖项的构造函数),因为 UserManager 和 SignInManager 在调用时都会自行解析...
如果我上网 http://localhost:58472/Account/Register
我有这个例外
System.InvalidOperationException:
The current type,IUserStore<ApplicationUser>
, is an interface and cannot be constructed. Are you missing a type mapping?
这是我的代码:
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;
}
}
这是控制器中的代码:
[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();
}
}
所以你看了我的代码就知道了,我在新建MVC项目的时候没有对原来的代码做任何改动,但是出现了上面的错误。我做错了什么?
我很好地制作了一个名为 ProfileController
的新控制器,其代码与我的第二个代码块中的代码相同,但没有 ApplicationSignInManager
,因为我不需要那个。
我还使用 Unity 容器来注册和管理服务。这是代码:
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));
}
}
如果我取消注释上面代码中的行,那么当我 运行 站点时没有任何区别。
更新:
根据@Jay 的评论,我在 Unity 管理器中添加了这段代码。
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
现在我遇到了这个异常:
System.InvalidOperationException
: The current type,System.Data.Common.DbConnection
, is an abstract class and cannot be constructed. Are you missing a type mapping?
这是堆栈跟踪中的一些信息:
InvalidOperationException
An error occurred when trying to create a controller of type
AccountController
. Make sure that the controller has a parameterless public constructor.是的,我有一个无参数的 public 构造函数。
ResolutionFailedException
Resolution of the dependency failed, type =
"AccountController"
, name ="(none)"
.
所以我在 Unity 管理器中添加了这一行:
container.RegisterType<IDbConnection, DbConnection>();
但我仍然有同样的异常。
The current type,
System.Data.Common.DbConnection
...
更新:
根据@RandyLevy 的评论,我试过了,帮助解决了这个问题 Configure Unity DI for ASP.NET Identity:
将此添加到
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; // } //}
将其添加到 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);
但是我在评论的行上遇到了这个错误(没有 运行 时间异常):
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>
.
我终于找到了解决问题的方法。我已将此代码添加到 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());
更新 H. Pauwelyn 的回答。最初的问题是 Unity 试图用两个参数调用构造函数。
public AccountController(
ApplicationUserManager userManager,
ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
}
下一行将告诉 Unity 改为调用无参数构造函数,不需要任何其他内容。这对我有用。
container.RegisterType<AccountController>(new InjectionConstructor());
或者,可以使用 [ApplicationUserManager userManager,ApplicationSignInManager signInManager] 从 AccountController 中删除构造函数,只留下一个无参数的构造函数(或一个具有统一解析依赖项的构造函数),因为 UserManager 和 SignInManager 在调用时都会自行解析...