Подтвердить что ты не робот

Инъекция зависимостей и провайдеры членства ASP.Net

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

Разве это не лучше? Я использую его с MVC3 и ninject. Этого достаточно, чтобы добавить свойство в ваш пользовательский класс поставщика членства. Не забудьте добавить "using System.Web.Mvc;" сверху.

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

Ответ 3

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

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

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.