是否可以创建一个Singleton工厂类来维护实例的字典?

时间:2017-06-08 15:47:14

标签: c# factory

我有多个继承自IPrint的类。我想使用工厂实例化这些类,但我想维护每种类型的单个实例。 这可能吗?

请在下面找到我的示例代码。

 public interface IPrint
    {
        void DoPrint();
    }
    public class DigitalPrint : IPrint
    {
        public void DoPrint()
        {
            // logic
        }
    }
    public class InkPrint : IPrint
    {
        public void DoPrint()
        {
            // logic
        }
    }
    public class PrintFactory
    {
        private static IDictionary<IPrint, object> prints = new 
   Dictionary<IPrint, object>();
        private PrintFactory()
        {

        }
        public static IPrint GetPrint(PrintType type)
        {
            // return instance depending on type. Instantiate only once 
             //like singleton
            // How to write so that it returns a single instance depending 
            //on type
            return null;
        }
    }

    public enum PrintType
    {
        DigitalPrint,
        InkPrint
    }

如果有可能,有人能给我一些想法吗?

感谢。

3 个答案:

答案 0 :(得分:1)

初始化IPrint时,您可以创建Dictionary<PrintType, IPrint>个实例:

private static IDictionary<PrintType, IPrint> prints = 
  new Dictionary<PrintType, IPrint> {
      { PrintType.DigitalPrint, new DigitalPrint() },
      { PrintType.InkPrint, new InkPrint() }
  };

获取打印(因此print是一个类,每个请求都会返回相同的实例):

public static IPrint GetPrint(PrintType type)
{
    IPrint print;
    if (!prints.TryGetValue(type, out print))
       return null;

    return print;
}

如果您不想在客户端要求之前创建IPrint实例,您可以使用Dictionary<PrintType, Lazy<IPrint>>

private static IDictionary<string, Lazy<IPrint>> prints =
    new Dictionary<string, Lazy<IPrint>> {
        { PrintType.DigitalPrint, new Lazy<IPrint>(() => new DigitalPrint()) },
        { PrintType.InkPrint, new Lazy<IPrint>(() => new InkPrint()) }
    };

获取打印(在这种情况下,将只创建每个IPrint类型的一个实例,但在有人试图获取该类型的实例之前不会创建):

public static IPrint GetPrint(PrintType type)
{
    Lazy<IPrint> factory;
    if (!prints.TryGetValue(type, out factory))
       return null;

    return factory.Value;
}

虽然我会考虑使用依赖注入框架,而不是手动实现这些功能。

进一步阅读:NinjectAutofac

答案 1 :(得分:0)

是的,这是可能的。

这会在他们需要之前创建IPrint。你可以让他们懒洋洋地创造它们。

public class Program
{
    public static void Main(string[] args)
    {
        var factory = new PrintFactory();
        Console.WriteLine(PrintFactory.GetPrint(PrintType.DigitalPrint));
        Console.WriteLine(PrintFactory.GetPrint(PrintType.InkPrint));
    }
}

public interface IPrint
{
    void DoPrint();
}

public class DigitalPrint : IPrint
{
    public void DoPrint()
    {
        // logic
    }
}

public class InkPrint : IPrint
{
    public void DoPrint()
    {
        // logic
    }
}

public class PrintFactory
{
    // Make the dictionary from PrintType to IPrint instead of IPrint to object
    private static IDictionary<PrintType, IPrint> prints = new Dictionary<PrintType, IPrint>();

    // Initialize prints in a static constructor.
    static PrintFactory()
    {
        prints.Add(PrintType.DigitalPrint, new DigitalPrint());
        prints.Add(PrintType.InkPrint, new InkPrint());
    }

    public static IPrint GetPrint(PrintType type)
    {
        if (!prints.ContainsKey(type)) 
        {
            // TODO: Maybe throw an exception or log?
        }
        return prints[type];
    }
}

public enum PrintType
{
    DigitalPrint,
    InkPrint
}

答案 2 :(得分:0)

我会摆脱枚举并制作通用方法:

public static IPrint GetPrint<T>() where T : IPrint, new ()
{
    foreach (var key in prints.Keys) {
        if (key is T)
            return null;
    }
           return new T();
}