具有依赖注入的单例

Shu*_*mov 5 c# dependency-injection castle-windsor inversion-of-control

我决定使用单例,以便在应用程序启动时加载一些文件,并在整个应用程序生命周期中使用此配置,因为此文件每年更改一次。有一个单例:

 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; } }
}
Run Code Online (Sandbox Code Playgroud)

在 Appstart 上我有:

 IWindsorContainer container = new WindsorContainer();
 container.Install(FromAssembly.This());
Run Code Online (Sandbox Code Playgroud)

在 WindsorInstaller 上我有:

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

我的读者类别如下:

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

似乎 Singleton 上没有发生注入,并且 reader 为 null,并且出现错误:对象引用未设置到对象的实例。您能否建议我做错了什么以及如何做得更好(可能根本不使用单例)?

Nko*_*osi 7

如果您的目的是将其与容器一起使用但仍然使用静态,那么您对具有依赖项注入的单例的概念有点倾斜。

另外你的类有一个private构造函数。容器如何显式地将依赖项注入到私有构造函数中?

构造预期单例的接口/抽象。

public interface ISingleton {
    Dictionary<string, HashSet<string>> Instance { get; }
}
Run Code Online (Sandbox Code Playgroud)

和实施...

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; } }
}
Run Code Online (Sandbox Code Playgroud)

然后将其作为单例注册到容器中

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

任何具有ISingeton依赖项的类都将在请求时获得注入的相同实例,并且单例实现将在解析时获得其依赖项。