2017-06-08 20 views
0

我有从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 
    } 

有人可以给我一些想法,如果这是可能的吗?

谢谢。

+0

也许静态的IDictionary <平面广告类型,IPRINT>打印=新词典<平面广告类型,IPRINT> ();在静态ctor中:打印[DigitalPrint] =新的DigitalPrint();打印[InkPrint] =新的InkPrint();在GetPrint中:return prints [type];一旦你创建了IPrint,那么你只能返回signle实例。 – DdarkSideE

回答

1

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

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

获取打印(因此印刷是一类,同一个实例会为每个请求返回):

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的类型只有一个实例将被创建,但在此之前有人试图获得该类型的实例):

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

延伸阅读:NinjectAutofac

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 
} 
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(); 
} 
相关问题