Pergunta

Estou no processo de criação de um provedor de associação personalizado para um site ASP.Net MVC.O provedor está sendo criado como uma classe separada como parte de uma biblioteca maior.É necessário que o armazenamento de dados de back-end seja flexível, pois pode ser um arquivo Xml ou um banco de dados SQL.Meu pensamento inicial foi criar uma interface para o armazenamento de dados e injetar isso no provedor usando injeção de dependência.

O resultado final necessário é que um desenvolvedor possa herdar a interface do armazenamento de dados e fornecer os métodos necessários para atualizar os dados, que serão então usados ​​pelos provedores de associação personalizada.

No entanto, devido à minha própria falta de habilidade, não consigo descobrir como injetar a classe no provedor de associação ao adicioná-la ao site.O que precisa ser feito para vincular o armazenamento de dados ao provedor?Qual seria a maneira mais simples de habilitar isso no site?

Foi útil?

Solução

Se você estiver configurando os provedores de associação personalizados por meio do elemento <membership> no arquivo Web.config, posso ver os problemas que você terá com a injeção de dependência.

Os provedores são construídos e gerenciados pela estrutura e não há oportunidade para você interceptar essa construção para fornecer injeção de dependência adicional para o IDataStore interface.

Se minha suposição estiver correta, então o que você pode fazer é substituir o Initialize() método em seu provedor personalizado e faça a injeção de dependência lá.Você pode ter uma configuração de nome/valor personalizada na configuração do provedor que aponta para um tipo que implementa IDataStore, que é passado como parte de um dicionário para o Initialize() método.

Em seguida, você ativa uma instância do tipo de armazenamento de dados e a configura na propriedade apropriada:

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á chamado pela estrutura depois de construir uma instância do seu provedor, então esse é o lugar perfeito para fazer qualquer trabalho de configuração adicional como este.

Para cenários de teste, basta definir a propriedade do armazenamento de dados na própria instância do provedor, pois você a construirá diretamente em seus testes.

Outras dicas

Não é melhor?Eu uso com MVC3 e ninject.Basta adicionar uma propriedade à sua classe de provedor de associação personalizada.Lembre -se de adicionar "Usando System.web.mvc;" em cima.

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

A maneira mais simples de fazer injeção de dependência que já vi (e na verdade a única que usei até agora...) é fazer com que um construtor da sua classe dependente tome a interface como parâmetro e atribua-a a um privado campo.Se desejar, você também pode adicionar um construtor "default", que encadeia o primeiro com um valor padrão.

Simplificado, ficaria mais ou menos assim:

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()) { }
}

O conceito é chamado de "Encadeamento de construtores" e há muitos artigos na web sobre como fazer isso.eu acho este tutorial muito explicativo do padrão DI.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top