2014-09-21 74 views
0

鑑於此代碼的主要方法初始化類:因爲是因爲MessageProvider實際上從未與InstanceFactory註冊如何在需要之前使用C#

using System; 
using System.Collections.Generic; 
using FactoryCallback = System.Func<System.Object>; 

interface IMessageProvider 
{ 
    string Message { get; } 
} 

class MessageProvider : IMessageProvider 
{ 
    private Random generator = new Random(); 

    public static void Register() 
    { 
     InstanceFactory.Register(typeof(IMessageProvider),() => new MessageProvider()); 
    } 

    public string Message 
    { 
     get 
     { 
      switch (generator.Next(3)) 
      { 
       case 0: 
        return "No matter where you go, there you are."; 
       case 1: 
        return "Once I thought I'd made a mistake, but I was wrong."; 
       case 2: 
        return "I used to think I was indecisive; now I'm not so sure"; 
       default: 
        throw new IndexOutOfRangeException(); 
      } 
     } 
    } 
} 

class InstanceFactory 
{ 
    private static Dictionary<Type, FactoryCallback> typeCallbacks = 
     new Dictionary<Type, FactoryCallback>(); 

    public static void Register(Type type, FactoryCallback callback) 
    { 
     typeCallbacks.Add(type, callback); 
    } 

    public static Object InstanceOf(Type type) 
    { 
     return typeCallbacks[type](); 
    } 
} 

public class RandomMessage 
{ 
    public static void Main() 
    { 
     IMessageProvider provider = 
      InstanceFactory.InstanceOf(typeof(IMessageProvider)) as IMessageProvider; 
     Console.WriteLine(String.Format("The message is:\n{0}", provider.Message)); 
    } 
} 

此程序將無法成功運行。 顯然,對MessageProvider.Register的調用可以添加到RandomMessage.Main的開頭。然而,現在需要使用RandomMessage來掌握MessageProvider的知識,並且破壞了InstanceFactory類的全部目的,該類旨在分離如何從某些事物中創建某些內容。 我想MessageProvider能夠在RandomMessage.Main嘗試創建一個IMessageProvider實例之前自動註冊到InstanceFactory。 這怎麼可能完成?

回答

0

假如你不小心調用InstanceFactory.InstanceOf()之前引用MessageProvider,你可以只添加一個static constructorMessageProvider類:

static MessageProvider() 
{ 
    Register(); 
} 

如果它不是一個選項,你可以通過反射做它通過添加custom attribute的所有類你想要在InstanceFactory的靜態構造函數中註冊並呼叫Register(),如所描述的here

+0

如果你從來沒有在執行流程引用'MessageProvider'類,無論是與一個靜態方法或通過實例化它,靜態構造函數將永遠不會被調用。 – greenboxal 2014-09-21 23:58:47

3

服務IMessageProvider和組件的註冊MessageProviderInstanceFactory不是MessageProvider實施的責任義務,它是應用程序的基礎架構的關注,因此應在Main方法內進行。

public class RandomMessage 
{ 
    public static void Main() 
    { 
     // Register services with InstanceFactory at the start of Main method 
     InstanceFactory.Register(typeof(IMessageProvider),() => new MessageProvider()); 

     IMessageProvider provider = InstanceFactory.InstanceOf(typeof(IMessageProvider)) as IMessageProvider; 
     Console.WriteLine(String.Format("The message is:\n{0}", provider.Message)); 
    } 
} 
0

考慮使用一些反轉控制庫。像Unity(但它可能是矯枉過正)或SimpleContainer。

然後,你將接口「註冊」實例,同時您的應用程序啓動(在例子,你應該有一個像「bootstrapper.cs」文件)

相關問題