Inyección de dependencia y ASP.Net Proveedores de Membresía


Estoy en el proceso de crear un proveedor de membresía personalizado para un ASP.Net Sitio web MVC. El proveedor se está creando como una clase separada como parte de una biblioteca más grande. Es necesario que el almacén de datos back-end 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 utilizando la inyección de dependencias.

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, a través de mi propia falta de habilidad no puedo averiguar cómo inyectar la clase en el proveedor de membresía al agregarla al sitio web? ¿Qué se debe hacer para vincular el almacén de datos al proveedor? ¿Cuál sería la forma más sencilla de habilitar esto en el sitio web?

Author: BinaryMisfit, 2009-10-11

3 answers

Si está configurando los proveedores de membresía personalizados a través del elemento en la Web.archivo de configuración, entonces puedo ver los problemas que tendrá con la inyección de dependencias.

Los proveedores son construidos y administrados por el framework, y no hay oportunidad de interceptar esa construcción para proporcionar una inyección de dependencia adicional para la interfaz IDataStore.

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

Luego, active una instancia del tipo data store y establézcala 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() será llamado por el framework después de que construya una instancia de su proveedor, por lo que es el lugar perfecto para hacer cualquier trabajo de configuración adicional como este.

Para los escenarios de prueba, simplemente establezca la propiedad data store en la propia instancia del proveedor, ya que la construirá directamente en sus pruebas.

 33
Author: Sam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-12 00:02:43

No es esto mejor? Lo uso con MVC3 y ninject. Basta con agregar una propiedad a tu clase de proveedor de membresía personalizada. Recuerde agregar " usando el sistema.Web.Mvc; " en la parte superior.

public IRepository Repository
{
    get
    {
        return DependencyResolver.Current.GetService<IRepository>();
    }
}
 20
Author: Michal B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-04 10:22:22

La forma más sencilla de hacer la inyección de dependencia que he visto (y en realidad la única que he utilizado hasta ahora...) es hacer que un constructor de su clase dependiente tome la interfaz como un parámetro y la asigne a un campo privado. Si lo desea, también puede agregar un constructor "default", 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 constructor" , y hay muchos artículos sobre el web sobre cómo hacerlo. Encuentro este tutorial muy explicativo del patrón DI.

 2
Author: Tomas Lycken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-11 23:32:32