C# Singleton工厂生成多个Singleton实例

C# Singleton工厂生成多个Singleton实例,c#,singleton,C#,Singleton,在我的项目中,我有两个单身班 public class VStateManager : IVState { private static readonly object _createLock = new object(); private static VStateManager _vsManager = null; public static VStateManager GetVStateManager() { lock (_createLoc

在我的项目中,我有两个单身班

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;
        }
    }
}
我的同事建议创建一个单例类(
类似于单例工厂
),它接受一个通用接口并生成这两个
单例对象


这怎么办

首先,您的类根本没有实现单例。看看这个:

if (_vsManager == null)
{
   return new VStateManager();
}
return _vsManager;
\u vsManager
将始终为空,因此每次访问实例时都会创建多个实例。应该是:

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()
。毫无理由地过度复杂化代码是编程中所有问题的根源,不要试图解决不存在的问题,因为这种解决方案可能会产生实际问题。

您正在寻找的单例工厂可以使用泛型创建。您需要传递需要为其创建单例实例的类型,工厂将返回该类型的实例,并确保仅创建该类型的一个实例

这种单例工厂的基本实现如下所示

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;
    }
}
公共静态类SingletonFactory
{
私有静态只读对象lockObject=新对象();
//用于存储单例对象的字典
私有静态只读字典singletonObjects=new Dictionary();
//方法检索单例实例。
//注意约束“new()”。这表示可以为具有默认构造函数的类型调用此方法。
公共静态T GetSingletoneInstance(),其中T:new()
{
var typeName=typeof(T).Name;
T例;
锁定(锁定对象)
{
//如果实例已经存在,请在字典中进行检查。
if(singletonObjects.ContainsKey(typeName))
{
//从字典中检索实例。
实例=(T)singletonObjects[typeName];
}
其他的
{
//如果字典里没有它,
//创建一个新实例
//并将其存储在字典中。
锁定(锁定对象)
{
实例=新的T();
添加(typeName,instance);
}
}
}
//返回从字典中检索到的类型为“T”的实例
//或者新创建的一个。
返回实例;
}
}
以下是您如何使用此工厂

class Program
{

static void Main(string[] args)
    {
        var vstateManager = SingletonFactory.GetSingletoneInstance<VStateManager>();

        var vehicleFactory = SingletonFactory.GetSingletoneInstance<VehicleFactory>();

        Console.ReadKey();
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var vstateManager=SingletonFactory.GetSingletoneInstance();
var vehicleFactory=SingletonFactory.GetSingletoneInstance();
Console.ReadKey();
}
}
SingletonFactory的实现是一个非常基本的版本。并且它有一个局限性,即它只能用于具有默认构造函数的类型

但是可以进一步扩展到使用DI模块初始化实例,而不必担心它们的构造函数。此外,它还可以扩展到将实例存储在其他地方,然后再存储到字典中,例如缓存、memcaches或数据库

我希望这能帮你得到你想要的东西