当前的类型IUserStore和DbConnection分别是接口和抽象类,无法构造
本文关键字:抽象类 接口 DbConnection 类型 IUserStore ApplicationUser | 更新日期: 2023-09-27 18:35:13
如果我冲浪到http://localhost:58472/Account/Register
我有这个例外
System.InvalidOperationException:
当前类型IUserStore<ApplicationUser>
是一个接口,无法构造。是否缺少类型映射?
这是我的代码:
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
:当前类型System.Data.Common.DbConnection
是一个抽象类,不能构造。是否缺少类型映射?
下面是堆栈跟踪中的一些信息:
InvalidOperationException
尝试创建类型
AccountController
的控制器时出错。确保控制器具有无参数公共构造函数。是的,我有一个无参数的公共构造函数。
ResolutionFailedException
依赖项解析失败,类型 =
"AccountController"
,名称 ="(none)"
。
所以我在 Unity 管理器中添加了这一行:
container.RegisterType<IDbConnection, DbConnection>();
但我仍然有同样的例外。
当前类型,
System.Data.Common.DbConnection
...
更新:
通过@RandyLevy的评论,我尝试过这个,通过这个问题帮助为 ASP.NET 身份配置 Unity DI:
将此添加到
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);
但是我在带有注释的行上遇到了此错误(没有运行时异常):
类型
RoleStore<IdentityRole>
不能用作以下泛型类型或方法中的类型参数TTo
:UnityContainerExtensions.RegisterType<TFrom, TTo> (IUnityContainer, params InjectionMember[])
没有从
RoleStore<IdentityRole>
到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
中删除构造函数,只保留一个无参数构造函数(或具有 Unity 解析依赖项的构造函数),因为UserManager
和SignInManager
在调用时都会自行解析......