Внедрение зависимостей и поставщиков членства в ASP.Net - PullRequest
34 голосов
/ 11 октября 2009

Я нахожусь в процессе создания настраиваемого поставщика членства для веб-сайта ASP.Net MVC. Поставщик создается как отдельный класс как часть большой библиотеки. Необходимо, чтобы внутреннее хранилище данных было гибким, поскольку это может быть база данных Xml File или SQL. Сначала я хотел создать интерфейс для хранилища данных и внедрить его в провайдер с помощью внедрения зависимостей.

Конечным результатом является то, что разработчик может унаследовать интерфейс хранилища данных и предоставить необходимые методы для обновления данных, которые затем будут использоваться поставщиками пользовательских членств.

Однако из-за отсутствия собственных навыков я не могу понять, как внедрить класс в провайдера членства при добавлении его на веб-сайт? Что нужно сделать, чтобы связать хранилище данных с провайдером? Какой самый простой способ включить это на веб-сайте?

Ответы [ 3 ]

33 голосов
/ 12 октября 2009

Если вы настраиваете пользовательских провайдеров членства через элемент в файле Web.config, то я могу видеть проблемы, которые у вас возникнут с внедрением зависимостей.

Поставщики создаются и управляются платформой, и у вас нет возможности перехватить эту конструкцию, чтобы обеспечить дополнительное внедрение зависимостей для интерфейса IDataStore.

Если мои предположения верны, то вы можете переопределить метод Initialize() в своем пользовательском провайдере и выполнить внедрение зависимостей там. В конфигурации провайдера может быть пользовательская настройка имени / значения, которая указывает на тип, реализующий IDataStore, который передается как часть словаря методу Initialize().

Затем вы активируете экземпляр типа хранилища данных и задаете для него соответствующее свойство:

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() будет вызываться платформой после создания экземпляра вашего провайдера, так что это идеальное место для выполнения любой дополнительной работы по настройке, такой как эта.

Для тестовых сценариев вы просто устанавливаете свойство хранилища данных на самом экземпляре провайдера, так как вы будете создавать его непосредственно в своих тестах.

20 голосов
/ 04 декабря 2011

Разве это не лучше? Я использую это с MVC3 и ninject. Достаточно добавить свойство в свой класс провайдера членства. Не забудьте добавить «using System.Web.Mvc;» сверху.

public IRepository Repository
{
    get
    {
        return DependencyResolver.Current.GetService<IRepository>();
    }
}
2 голосов
/ 12 октября 2009

Простейший способ внедрения зависимости, который я видел (и фактически единственный, который я использовал до сих пор ...), - это заставить конструктор вашего зависимого класса взять интерфейс в качестве параметра и назначить его. в частном поле. При желании вы также можете добавить конструктор «по умолчанию», который объединяет первый конструктор со значением по умолчанию.

Упрощенно, это будет выглядеть примерно так:

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

Концепция называется "построение цепочек", и в Интернете есть много статей о том, как это сделать. Я считаю этот урок очень объяснительным для паттерна DI.

...