2011-04-08 19 views
18

Estoy tratando de inyectar un repositorio a un proveedor de suscripciones personalizado con ninject en MVC 3.repositorio para el proveedor de suscripciones personalizado con Ninject

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 he intentado lo siguiente:

Bind<MembershipProvider>().ToConstant(Membership.Provider); 

Ninguno de los anteriores funciona.

Cuando uso (en global.asa)

kernel.Inject(Membership.Provider); 

junto con

[Inject] 
public ICustomerRepository _customerRepository{ get; set; } 

funciona, pero no tengo ni la gestión de ciclo de vida y esto causará un error "ISession está abierto" de NHibernate, porque ISession es InRequestScope y el repositorio no lo es.

+0

He estado atrapado en esta cosa de meses. –

Respuesta

1

El problema es que toda la infraestructura de membresía es un código .NET "nativo" (System.Web.Security) que no conoce MVC y sobre 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 ninguna posibilidad de activarse y establecer la dependencia de su repositorio en el resultado. Si configura explícitamente la instancia devuelta con Ninject, puede funcionar, porque explícitamente le dio a Ninject el objeto para establecer las dependencias. Incluso en este caso, solo puede funcionar con inyección de propiedad y no con inyección de constructor, porque la instancia es creada previamente por la configuración de membresía.

En resumen: no se pueden insertar dependencias fácilmente en el proveedor de membresía porque no se resuelve desde un contenedor de inyección de dependencia. yo creo que hay 2 posibilidades:

  1. crea un repositorio en el proveedor de suscripciones personalizado directamente o acceder a él por algún otro medio a la carta (donde el contexto web ya está presente).
  2. Usted va un nivel más arriba y verifica los componentes que usarían su proveedor de membresía e intenta cambiar allí (para usar un proveedor de membresía resuelto de su contenedor DI en lugar del proveedor de Memeship no inicializado). Si este "componente de mayor" es la autenticación de formularios, entonces este artículo podría ser de ayuda (mediante 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
+0

Me preguntaba por qué no puedo encontrar la interfaz IMembershipService en la biblioteca de MVC: obtendrá una generada por la plantilla de Visual Studio como se describe aquí http://stackoverflow.com/questions/2349022/how-do-i-get- an-instancia-de-un-asp-net-mvc-applications-membershipprovider-de –

0

¿Usted intentó resolver su repositorio "manualmente", al igual que en esta respuesta: Ninject : Resolving an object by type _and_ registration name/identifier ?

+0

¿Pero todavía necesito obtener la instancia del kernel de alguna manera? – Luticka

+0

Si registra su repositorio en su implementación de IModule (es decir,MyModule: IModule), a continuación, para obtener una instancia del kernel necesita llamar 'iKernel kernel = new StandardKernel (nueva MyModule());' ver http://ninject.codeplex.com/wikipage?title=Modules%20and% 20el% 20Kernel –

5

Puede usar el método @Remo Gloor outlines in his blog post on provider injection.Se trata de 3 pasos:

  1. Añadir [Inject] s a las propiedades de su proveedor que necesita inyectado (aunque el patrón se muestra - la creación de una clase muy simple cuya única función es ser un receptáculo para la inyección propiedad y hacia delante cualquier solicitud a una clase de bienes implementan mediante la inyección de constructor - está bien vale la pena seguir)

    public class MyMembershipProvider : SqlMembershipProvider 
    { 
        [Inject] 
        public SpecialUserProvider SpecialUserProvider { get;set;} 
        ... 
    
  2. crear una envoltura de inicialización que implementa IHttpModule que tira del proveedor en el, lo que provocó su creación: -

    public class ProviderInitializationHttpModule : IHttpModule 
    { 
        public ProviderInitializationHttpModule(MembershipProvider membershipProvider) 
        { 
        } 
    ... 
    
  3. Registrar el IHttpModule en su RegisterServices: -

    kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>(); 
    
  4. no hay 4; Ninject se encarga del resto: arranca todos los registros IHttpModules, incluido el que ha agregado, durante la secuencia de inicio.

(No se olvide de leer los comentarios en el blog re cursos de la vida, etc.)


Por último, si usted está buscando algo completamente braindead directa que resuelve limpiamente, tratar this @Remo Gloor answer instead


PS una gran valoración crítica de todo el lío es Provider is not a Pattern by @Mark Seemann. (Y el tapón oboligatory por su excelente libro: - Dependency injection in .NET que tendrá que calcular esta materia hacia fuera con comodidad a partir de primeros principios)

2

he tenido este problema

una membresía personalizada, el papel y el proveedor de perfil en otro proyecto de MVC usando el repositorio, cada vez que 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 es siempre nulo, porque asp.net tiene su propia propiedad estática para membership.which membership.provider. y esta instancia no es parte de la administración de instancias de instancias.

a fin de utilizar el PostApplicationStartMethod

aquí es la soloution por Cipto añadir a la NinjectWebCommon attrbute y 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); 
    } 
Cuestiones relacionadas