我的项目中有两个单例类。
public class VStateManager : IVState
{
private static readonly object _createLock = new object();
private static VStateManager _vsManager = null;
public static VStateManager GetVStateManager()
{
lock (_createLock)
{
if (_vsManager == null)
{
return new VStateManager();
}
return _vsManager;
}
}
}
public class VTRFactory : IVTR
{
private static VehicleFactory _VTRFactory =null;
private static readonly object _createLock = new object();
public static VehicleFactory GetVTRFactory()
{
lock(_createLock)
{
if(_VTRFactory == null)
{
return new VTRFactory();
}
return _VTRFactory;
}
}
}
我的同事建议创建一个单例类(something like a singleton factory
),它接受一个通用接口并生成这两个singleton objects
如何做到这一点。
答案 0 :(得分:2)
首先,你的类根本没有实现单例。看看这个:
if (_vsManager == null)
{
return new VStateManager();
}
return _vsManager;
_vsManager
将始终为null,因此每次访问实例时都会创建多个实例。它应该是:
if (_vsManager == null)
{
_vsManager = new VStateManager();
}
return _vsManager;
这就是确保只创建一个实例的方式。
另外,我会使用属性而不是函数,它更清楚:
public class VStateManager : IVState
{
private static readonly object _createLock = new object();
private static VStateManager _vsManager = null;
public static VStateManager Instance
{
get
{
lock (_createLock)
{
if (_vsManager == null)
{
_vsManager = new VStateManager();
}
return _vsManager;
}
}
}
}
然后您可以使用每个示例VStateManager.Instance.XXX
。
其次,为什么你需要第三堂课来创造这些单身人士?当你需要使用它们来访问GetXXXX
时会创建所需的实例,有没有理由在你需要之前创建这些实例?
如果您真的需要在需要之前初始化这些实例,那么您可以做一些非常简单的事情:
public static class Initializer()
{
public static void Init()
{
var a = VStateManager.GetVStateManager();
var b = VehicleFactory.GetVTRFactory();
}
}
然后初始化只需致电Initializer.Init()
。无任何理由过度复杂代码是编程中所有邪恶的根源,不要试图解决不存在的问题,因为该解决方案可能会产生实际问题。
答案 1 :(得分:1)
您正在寻找的单件工厂可以使用泛型创建。您需要传递您需要创建单例实例的类型,并且工厂将返回该类型的实例,并确保只创建该类型的一个实例。
这种单件工厂的基本实现如下:
public static class SingletonFactory
{
private static readonly object lockObject = new object();
//Dictionary to store the singleton objects
private static readonly Dictionary<string, object> singletonObjects = new Dictionary<string, object>();
// Method to retrieve singleton instance.
// Note the constraint "new ()". This indicates that this method can be called for the types which has default constructor.
public static T GetSingletoneInstance<T>() where T:new ()
{
var typeName = typeof(T).Name;
T instance;
lock (lockObject)
{
// Check in the dictionary if the instance already exist.
if (singletonObjects.ContainsKey(typeName))
{
//Retrieve the instance from the dictionary.
instance = (T) singletonObjects[typeName];
}
else
{
// If it does not exist in the dictionary,
// create a new instance
// and store it in the dictionary.
lock (lockObject)
{
instance = new T();
singletonObjects.Add(typeName, instance);
}
}
}
// Return the instance of type "T" either retrieved from dictionary
// or the newly created one.
return instance;
}
}
以下是您如何使用此工厂。
class Program
{
static void Main(string[] args)
{
var vstateManager = SingletonFactory.GetSingletoneInstance<VStateManager>();
var vehicleFactory = SingletonFactory.GetSingletoneInstance<VehicleFactory>();
Console.ReadKey();
}
}
SingletonFactory的实现是一个非常基本的版本。并且它具有限制,它只能用于具有默认构造函数的类型。
但是可以进一步扩展到使用DI模块初始化实例而不必担心它们的构造函数。此外,它还可以扩展为将实例存储在其他地方,然后是字典,如缓存,内存缓存或数据库。
我希望这可以帮助你得到你想要的任何东西。