c# - pattern - Configurar Unity DI para la identidad de ASP.NET
dependency injection in asp net core (4)
Estoy usando Unity con éxito para todas las inyecciones regulares de constructores, como repositorios, etc., pero no puedo hacer que funcione con las clases de identidad de ASP.NET. La configuración es la siguiente:
public class AccountController : ApiController
{
private UserManager<ApplicationUser> _userManager { get; set; }
public AccountController(UserManager<ApplicationUser> userManager)
{
if (userManager == null) { throw new ArgumentNullException("userManager"); }
_userManager = userManager;
}
// ...
}
Con estas configuraciones para la unidad:
unity.RegisterType<AccountController>();
unity.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
unity.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());
Es lo mismo que otras publicaciones aquí para Autofac, por ejemplo, Ninject, pero no funciona en mi caso. El mensaje de error es:
Se ha producido un error al intentar crear un controlador de tipo ''AccountController''. Asegúrese de que el controlador tenga un constructor público sin parámetros. Trabajos de creación manual por supuesto:
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>("Mongo")))
{
}
Que pasa
ACTUALIZAR
Según lo sugerido por @emodendroket, acortar el código para esto hace el truco. No es necesario el paquete Unity.Mvc.
unity.RegisterType<IUserStore<IdentityUser>,
MyCustomUserStore>(new HierarchicalLifetimeManager());
y
public AccountController(UserManager<IdentityUser> _userManager,
IAccountRepository _account)
{
// ...
Como esta publicación del blog de enterpriseframework.com dice:
Primero, agregue el paquete Unity Bootstrapper for ASP.NET MVC Nuget.
En su "Explorador de soluciones" de Visual Studio> haga clic derecho en el nodo "Referencias" de su proyecto Web> haga clic en "Administrar paquetes NuGet".
En el menú de la izquierda, elija Online> Todos
- En el cuadro de búsqueda superior derecho> Buscar en línea (Ctrl + E)> escriba "Unity bootstrapper for ASP.NET MVC".
- Seleccione "Unity Bootstrapper for ASP.NET MVC" y elija Instalar.
- Haga clic en Cerrar después de completar la instalación
Luego modifique your-Web-project/App_Start/UnityConfig.cs
archivo your-Web-project/App_Start/UnityConfig.cs
y actualice las declaraciones de using
siguiente manera:
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;
Finalmente, en el mismo archivo, actualice el método RegisterTypes
como se muestra a continuación:
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());
}
HTH
Reemplace esta propiedad en el AccountController
public ApplicationUserManager UserManager
{
get
{
_userManager = new ApplicationUserManager(
new UserStore<ApplicationUser>(new ApplicationDbContext()));
return _userManager ??
Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
También es necesario resolver el UserManager . El siguiente es un ejemplo de cómo podría hacerlo con UserManager y RoleManager . En este ejemplo, uso el paquete regular de Unity 3 en lugar de uno de los derivados o bootstrappers (tuve algunos problemas con ellos en el pasado).
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);
Install-Package Unity.AspNet.WebApi
HttpConfiguration.DependencyResolver
registrar Unity en la propiedad HttpConfiguration.DependencyResolver
. Esto le permite a WebApi
saber que necesita usar Unity en lugar de la reflexión para crear una instancia de sus controladores.
La forma más sencilla de hacerlo es con el paquete nuget anterior.