H. *_*lyn 5 c# asp.net-mvc user-management unity-container invalidoperationexception
如果我冲浪,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;
}
}
Run Code Online (Sandbox Code Playgroud)
这里是控制器的代码:
[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();
}
}
Run Code Online (Sandbox Code Playgroud)
所以你可以看看你是否阅读了我的代码,当你创建一个新的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));
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在上面的代码中取消注释行,则在运行站点时没有任何区别.
更新:
通过@Jay的评论,我在Unity管理器中添加了这段代码.
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
Run Code Online (Sandbox Code Playgroud)
现在我有这个例外:
System.InvalidOperationException:当前类型,System.Data.Common.DbConnection是一个抽象类,无法构造.你错过了类型映射吗?
以下是堆栈跟踪中的一些信息:
InvalidOperationException
尝试创建类型的控制器时发生错误
AccountController.确保控制器具有无参数的公共构造函数.
是的,我有一个没有参数的公共构造函数.
ResolutionFailedException
依赖项的解析失败,type =
"AccountController",name ="(none)".
所以我在Unity管理器中添加了这一行:
container.RegisterType<IDbConnection, DbConnection>();
Run Code Online (Sandbox Code Playgroud)
但我仍然有同样的例外.
目前的类型,
System.Data.Common.DbConnection......
更新:
通过@RandyLevy的评论我试过这个,帮助这个问题配置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;
// }
//}
Run Code Online (Sandbox Code Playgroud)将其添加到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);
Run Code Online (Sandbox Code Playgroud)但是我在注释的行上遇到了这个错误(没有运行时异常):
该类型
RoleStore<IdentityRole>不能用作TTo以下泛型类型或方法中的类型参数:Run Code Online (Sandbox Code Playgroud)UnityContainerExtensions.RegisterType<TFrom, TTo> (IUnityContainer, params InjectionMember[])没有来自隐式引用转换
RoleStore<IdentityRole>到IRoleStore<IdentityRole>.
H. *_*lyn 15
最后我找到了解决问题的方法.我已将此代码添加到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());
Run Code Online (Sandbox Code Playgroud)