Синглтон с инъекцией зависимостей - PullRequest
0 голосов
/ 08 мая 2018

Я решил использовать синглтон для загрузки некоторого файла при запуске приложения и использовать эту конфигурацию в течение всего срока службы приложения, так как этот файл изменяется один раз в год. Есть синглтон:

 public class Singleton
 {
    private static IReader reader;

    private Singleton(IReader reader)
    {
        Singleton.reader = reader;
    }

    private static readonly Lazy<Dictionary<string, HashSet<string>>> lazy =
    new Lazy<Dictionary<string, HashSet<string>>>(() => reader.ReadData("config") );


    public static Dictionary<string, HashSet<string>> Instance { get { return lazy.Value; } }
}

А на Appstart у меня есть:

 IWindsorContainer container = new WindsorContainer();
 container.Install(FromAssembly.This());

А на WindsorInstaller у меня есть:

public class WindsorInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For<IReader>().ImplementedBy<MyReader>());
    }
}

Мой класс читателя следующий:

 public class MyReader : IReader
 {
    public Dictionary<string, HashSet<string>> ReadData(string source)
    {
        /*some code*/
        return dict;
    }
 }

Кажется, что в Singleton не происходит инъекция, и читатель равен null, и я получаю ошибку: ссылка на объект не установлена ​​для экземпляра объекта. Подскажите, пожалуйста, что я делаю неправильно и как это сделать лучше (возможно, не использовать синглтон вообще)?

1 Ответ

0 голосов
/ 08 мая 2018

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

Плюс у вашего класса есть конструктор private. Как контейнер предполагает явное внедрение зависимостей в закрытый конструктор?

Построить интерфейс / абстракцию предполагаемого синглтона.

public interface ISingleton {
    Dictionary<string, HashSet<string>> Instance { get; }
}

и реализация ...

public class Singleton: ISingleton {
    private readonly Lazy<Dictionary<string, HashSet<string>>> lazy;

    public Singleton(IReader reader) {
        this.lazy = new Lazy<Dictionary<string, HashSet<string>>>(() => reader.ReadData("config") );
    }

    public Dictionary<string, HashSet<string>> Instance { get { return lazy.Value; } }
}

Затем вы регистрируете его в контейнере как одноэлементный

public class WindsorInstaller : IWindsorInstaller {
    public void Install(IWindsorContainer container, IConfigurationStore store) {
        container.Register(Component.For<IReader>().ImplementedBy<MyReader>());
        container.Register(Component.For<ISingleton>().ImplementedBy<Singleton>().LifestyleSingleton());
    }
}

Любой класс, имеющий ISingeton в качестве зависимости, получит тот же экземпляр, внедренный по запросу, и реализация Singleton получит свою зависимость при разрешении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...