asp.net mvc - unitofwork - Inyecte el repositorio al proveedor de membresía personalizado con Ninject
unit of work c# (4)
¿ Intentó resolver su repositorio "manualmente", como en esta respuesta: Proyectar: resolver un objeto por tipo _y_ nombre / identificador de registro ?
Estoy tratando de inyectar un repositorio a un proveedor de membresía personalizado con ninject en MVC 3.
En MembershipProvider he intentado lo siguiente:
[Inject]
public ICustomerRepository _customerRepository{ get; set; }
Y
[Inject]
public TUMembershipProvider(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
En mi módulo ninject probé lo siguiente:
Bind<MembershipProvider>().ToConstant(Membership.Provider);
Ninguna de las obras anteriores.
Cuando uso (en global.asa)
kernel.Inject(Membership.Provider);
Juntos con
[Inject]
public ICustomerRepository _customerRepository{ get; set; }
funciona, pero no tengo administración del ciclo de vida y esto causará un error "ISession is open" de NHibernate, porque ISession es InRequestScope y el repositorio no.
El problema es que toda la infraestructura de Membresía es un código .NET "nativo" (System.Web.Security) que no conoce MVC ni el contenedor DI utilizado por MVC. La llamada estática a Membership.Provider devuelve el proveedor de membresía según la configuración, sin embargo, el tipo de proveedor especificado se crea una instancia con una simple llamada Activator.CreateInstance. Por lo tanto, la inyección de dependencia no tiene la posibilidad de activarse y establecer la dependencia del repositorio en el resultado. Si configura explícitamente la instancia devuelta con Ninject, puede funcionar, porque le dio explícitamente a Ninject el objeto para establecer las dependencias. Incluso en este caso, solo puede funcionar con la inyección de propiedades y no con la inyección de constructor, porque la instancia es creada previamente por la configuración de membresía.
Para resumir: no puede inyectar fácilmente dependencias en el proveedor de membresía porque no se resuelve desde un contenedor de inyección de dependencia. Creo que tienes 2 posibilidades:
- Puede crear un repositorio en el proveedor de membresía personalizado directamente o acceder a él por otros medios a pedido (donde el contexto web ya está presente).
- Sube un nivel más alto y verifica los componentes que utilizarían su proveedor de membresía e intenta cambiar allí (para usar un proveedor de membresía resuelto desde su contenedor DI en lugar de la Membresía no habilitada. Proveedor). Si este "componente superior" es la autenticación de formularios, este artículo podría ser de ayuda (utilizando la inyección de dependencia con IFormsAuthentication y IMembershipService): http://weblogs.asp.net/shijuvarghese/archive/2009/03/12/applying-dependency-injection-in-asp-net-mvc-nerddinner-com-application.aspx
Podría usar el enfoque que @Remo Gloor describe en su blog sobre la inyección del proveedor . Se trata de 3 pasos:
Agregue
[Inject]
a cualquier propiedad de su proveedor que necesite inyectar (aunque el patrón que muestra muestra una clase muy simple cuya única función es ser un receptor para la inyección de propiedad y reenvía cualquier solicitud a una clase real implementada usando la inyección de constructor - Vale la pena seguirlopublic class MyMembershipProvider : SqlMembershipProvider { [Inject] public SpecialUserProvider SpecialUserProvider { get;set;} ...
Cree un contenedor de inicializador que implemente
IHttpModule
queIHttpModule
al proveedor, lo que desencadena su creación:public class ProviderInitializationHttpModule : IHttpModule { public ProviderInitializationHttpModule(MembershipProvider membershipProvider) { } ...
Registre el
IHttpModule
en sus servicios deRegisterServices
:kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();
no hay 4; Ninject se encarga del resto: reinicia todos los
IHttpModules
registrados, incluido el que ha agregado, durante la secuencia de inicio.
(No olvides leer los comentarios en la publicación del blog sobre la vida útil, etc.)
Por último, si estás buscando algo completamente sencillo que lo resuelva perfectamente, prueba esta respuesta de @Remo Gloor.
PD: una gran reseña de todo el lío es que Provider no es un patrón de @Mark Seemann . (y el complemento obligatorio de su excelente libro: - Inyección de dependencia en .NET, que te ayudará a descifrar estas cosas cómodamente desde los primeros principios)
tuve este problema
un miembro personalizado, función y proveedor de perfil en otro proyecto de MVC usando repositorio, cuando llamo al proveedor, el repositorio inyectado era nulo.
intentó llamar a kernel.Inject (Membership.Provider); en el método NinjectWebCommon registerServices (kernel de IKernel) pero obtuvo la excepción
El resultado siempre es nulo, porque asp.net tiene su propia propiedad estática para membership.which es membership.provider. y esta instancia no es parte de la administración de ninject de instancia.
así que use en PostApplicationStartMethod
Aquí está la solución por cipto, agregue a NinjectWebCommon el atributo y el método:
[assembly: WebActivator.PreApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "RegisterMembership")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(WebApp.App_Start.NinjectWebCommon), "Stop")]
public static void RegisterMembership()
{
bootstrapper.Kernel.Inject(Membership.Provider);
}