Inyección de dependencia y proveedores de membresía ASP.Net

Estoy en el proceso de crear un proveedor de membresía personalizado para un sitio web ASP.Net MVC. El proveedor se está creando como una clase separada como parte de una biblioteca más grande. Existe la necesidad de que el almacén de datos de fondo sea flexible, ya que podría ser un archivo Xml o una base de datos SQL. Mi idea inicial fue crear una interfaz para el almacén de datos e inyectar esto en el proveedor usando la dependency injection.

El resultado final es que un desarrollador puede heredar la interfaz del almacén de datos y proporcionar los métodos necesarios para actualizar los datos, que luego serán utilizados por los proveedores de membresía personalizados.

Sin embargo, debido a mi propia falta de habilidad, ¿no puedo imaginar cómo inyectar la clase en el proveedor de membresía cuando la agrego al sitio web? ¿Qué se necesita hacer para vincular el almacén de datos con el proveedor? ¿Cuál sería la forma más sencilla de habilitar esto en el sitio web?

    Si está configurando los proveedores de membresía personalizados a través del elemento en el archivo Web.config, entonces puedo ver los problemas que tendrá con la dependency injection.

    Los proveedores son construidos y gestionados por el marco, y no hay oportunidad para que intercepte esa construcción para proporcionar dependency injection adicional para la interfaz IDataStore .

    Si mi suposición es correcta, entonces lo que puede hacer es anular el método Initialize() en su proveedor personalizado y realizar allí la dependency injection. Puede tener una configuración personalizada de nombre / valor en la configuración del proveedor que apunta a un tipo que implemente IDataStore , que se pasa como parte de un diccionario al método Initialize() .

    Luego, activa una instancia del tipo de almacén de datos y lo configura en la propiedad apropiada:

     public class MyMembershipProvider : MembershipProvider { public IDataStore DataStore { get; set; } public override Initialize(string name, NameValueCollection config) { var dataStoreType = config["dataStoreProvider"]; if (!String.IsNullOrEmpty(dataStoreType)) { var type = Type.GetType(dataStoreType); DataStore = (IDataStore) Activator.CreateInstance(type); } } } 

    Initialize() framework llamará a Initialize() después de que construya una instancia de su proveedor, por lo que es el lugar perfecto para realizar cualquier trabajo de configuración adicional como este.

    Para los escenarios de prueba, simplemente establece la propiedad del almacén de datos en la instancia del proveedor, ya que la construirá directamente en sus pruebas.

    ¿No es esto mejor? Lo uso con MVC3 y ninject. Es suficiente agregar una propiedad a su clase de proveedor de membresía personalizada. Recuerde agregar “using System.Web.Mvc;” en la parte superior.

     public IRepository Repository { get { return DependencyResolver.Current.GetService(); } } 

    La forma más simple de hacer la dependency injection que he visto (y en realidad la única que he usado hasta ahora …) es hacer que un constructor de tu clase dependiente tome la interfaz como parámetro y asignarla a un sistema privado. campo. Si lo desea, también puede agregar un constructor “predeterminado”, que encadena al primero con un valor predeterminado.

    Simplificado, se vería algo como esto:

     public class DependentClass { private IDataStore _store; // Use this constructor when you want strict control of the implementation public DependentClass(IDataStore store) { this._store = store; } // Use this constructor when you don't want to create an IDataStore instance // manually every time you create a DependentClass instance public DependentClass() : this(new DefaultDataStore()) { } } 

    El concepto se llama “encadenamiento de constructores” y hay muchos artículos en la web sobre cómo hacerlo. Encuentro este tutorial muy explicativo del patrón DI.