具有依赖注入的单例
Singleton with Dependency Injection
我决定使用单例,以便在应用程序启动时加载一些文件,并在整个应用程序生命周期中使用此配置,因为此文件每年更改一次。
有一个单例:
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>());
}
}
我的 reader class 如下:
public class MyReader : IReader
{
public Dictionary<string, HashSet<string>> ReadData(string source)
{
/*some code*/
return dict;
}
}
似乎在 Singleton 上没有发生注入,reader 为空,我得到错误:未将对象引用设置为对象的实例。您能否建议我做错了什么以及如何做得更好(可能根本不使用单例)?
如果打算将其与容器一起使用但仍使用静态,那么您对具有依赖项注入的单例的概念有点偏差。
此外,您的 class 有一个 private
构造函数。容器应该如何显式地将依赖项注入私有构造函数?
构造预期单例的interface/abstraction。
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
作为依赖项的 class 将在请求时注入相同的实例,并且 Singleton 实现将在解析时获得其依赖项。
我决定使用单例,以便在应用程序启动时加载一些文件,并在整个应用程序生命周期中使用此配置,因为此文件每年更改一次。 有一个单例:
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>());
}
}
我的 reader class 如下:
public class MyReader : IReader
{
public Dictionary<string, HashSet<string>> ReadData(string source)
{
/*some code*/
return dict;
}
}
似乎在 Singleton 上没有发生注入,reader 为空,我得到错误:未将对象引用设置为对象的实例。您能否建议我做错了什么以及如何做得更好(可能根本不使用单例)?
如果打算将其与容器一起使用但仍使用静态,那么您对具有依赖项注入的单例的概念有点偏差。
此外,您的 class 有一个 private
构造函数。容器应该如何显式地将依赖项注入私有构造函数?
构造预期单例的interface/abstraction。
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
作为依赖项的 class 将在请求时注入相同的实例,并且 Singleton 实现将在解析时获得其依赖项。