Настройка Unity DI для идентификации ASP.NET
Я использую Unity успешно для всех регулярных инъекций конструктора, таких как репозитории и т.д., но я не могу заставить его работать с классами ASP.NET Identity. Настройка такова:
public class AccountController : ApiController
{
private UserManager<ApplicationUser> _userManager { get; set; }
public AccountController(UserManager<ApplicationUser> userManager)
{
if (userManager == null) { throw new ArgumentNullException("userManager"); }
_userManager = userManager;
}
// ...
}
с этими конфигами для Unity:
unity.RegisterType<AccountController>();
unity.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
unity.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());
То же, что и другие сообщения здесь для Autofac, Ninject, например, но это не работает в моем случае. Сообщение об ошибке:
Произошла ошибка при попытке создать контроллер типа AccountController. Удостоверьтесь, что контроллер имеет безкоммертный публичный конструктор. Конечно, ручные работы:
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>("Mongo")))
{
}
Что не так?
UPDATE
Как было предложено @emodendroket, сокращение кода до этого делает трюк. Нет необходимости в пакете Unity.Mvc.
unity.RegisterType<IUserStore<IdentityUser>,
MyCustomUserStore>(new HierarchicalLifetimeManager());
и
public AccountController(UserManager<IdentityUser> _userManager,
IAccountRepository _account)
{
// ...
Ответы
Ответ 1
Вам также нужно решить UserManager. Ниже приведен пример того, как вы могли бы сделать это с помощью UserManager и RoleManager. В этом примере я использую обычный пакет Unity 3 вместо одного из дериватов или загрузчиков (с некоторыми проблемами с ними в прошлом).
AccountController
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
public AccountController(IUserStore<ApplicationUser> userStore, IRoleStore<IdentityRole> roleStore)
{
_userManager = new UserManager<ApplicationUser>(userStore);
_roleManager = new RoleManager<IdentityRole>(roleStore);
}
Unity Bootstrapper
var accountInjectionConstructor = new InjectionConstructor(new IdentitySampleDbModelContext(configurationStore));
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(accountInjectionConstructor);
container.RegisterType<IRoleStore<IdentityRole>, RoleStore<IdentityRole>>(accountInjectionConstructor);
Ответ 2
Как говорится в сообщении в блоге от enterpriseframework.com:
Сначала добавьте Unity Bootstrapper для пакета ASP.NET MVC Nuget.
Затем измените файл your-Web-project/App_Start/UnityConfig.cs
и обновите операторы using
следующим образом:
using System;
using System.Data.Entity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using MicrosoftIdentity.Controllers;
using MicrosoftIdentity.Models;
Наконец, в том же файле обновите метод RegisterTypes
, как показано ниже:
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your types here
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
container.RegisterType<UserManager<ApplicationUser>>();
container.RegisterType<DbContext, ApplicationDbContext>();
container.RegisterType<ApplicationUserManager>();
container.RegisterType<AccountController>(new InjectionConstructor());
}
НТН
Ответ 3
Install-Package Unity.AspNet.WebApi
Вам нужно зарегистрировать Unity в свойстве HttpConfiguration.DependencyResolver
. Это позволяет WebApi
знать, что для использования контроллеров необходимо использовать Unity, а не рефлексию.
Самый простой способ сделать это - с указанным выше пакетом nuget.
Ответ 4
Замените это свойство в AccountController
public ApplicationUserManager UserManager
{
get
{
_userManager = new ApplicationUserManager(
new UserStore<ApplicationUser>(new ApplicationDbContext()));
return _userManager ??
Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}