2012-10-15 31 views
0

好的首先我要說的是,我所想的是創建屬性並使用該屬性來自動創建用該屬性裝飾的類的實例。真的有可以在我的情況下構建的類的實現,我不想在這裏使用IoC容器,因爲首先我認爲它們不會被創建直到被請求爲止,其次這僅適用於需要自動實例化的特殊類集主要是服務類。下面是用於創建單如何在NET程序集中自動初始化任何類

public abstract class Singleton<T> where T : class 
{ 
    private readonly IEventAggregator _eventAggregator = 
     ServiceLocator.Current.GetInstance<IEventAggregator>(); 

    private static readonly Lazy<T> Instance 
     = new Lazy<T>(() => 
          { 
           ConstructorInfo[] ctors = typeof(T).GetConstructors(
            BindingFlags.Instance 
            | BindingFlags.NonPublic 
            | BindingFlags.Public); 
           if (ctors.Count() != 1) 
            throw new InvalidOperationException(
             String.Format("Type {0} must have exactly one constructor.", typeof(T))); 
           ConstructorInfo ctor = 
            ctors.SingleOrDefault(c => !c.GetParameters().Any() && c.IsPrivate); 
           if (ctor == null) 
            throw new InvalidOperationException(
             String.Format(
              "The constructor for {0} must be private and take no parameters.", 
              typeof(T))); 
           return (T)ctor.Invoke(null); 
          }); 

    public static T Current 
    { 
     get { return Instance.Value; } 
    } 
} 

這裏的代碼實現,則其被定義爲單

public class PersonService : Singleton<PersonService>, IPersonService 
{ 
    private PersonService() 
    { 
     RegisterForEvent<PersonRequest>(OnPersonRequered); 
     //_serviceClient = ServiceLocator.Current.GetInstance<ICuratioCMSServiceClient>(); 
    } 
} 

Hwre而來的代碼用來解決這就需要將所有類型的樣本類活性。

public class InitOnLoad : Attribute 
{ 
    public static void Initialise() 
    { 
     // get a list of types which are marked with the InitOnLoad attribute 
     var types = 
      from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()) 
      where t.GetCustomAttributes(typeof(InitOnLoad), false).Any() 
      select t; 

     // process each type to force initialize it 
     foreach (var type in types) 
     { 
      // try to find a static field which is of the same type as the declaring class 
      var field = 
       type.GetFields(System.Reflection.BindingFlags.Static 
           | System.Reflection.BindingFlags.Public 
           | System.Reflection.BindingFlags.NonPublic 
           | System.Reflection.BindingFlags.Instance).FirstOrDefault(f => f.FieldType == type); 
      // evaluate the static field if found 
      //if (field != null) field.GetValue(null); 
     } 
    } 
} 

我發現Stackoverflow上的代碼片段,我認爲它非常有趣,但沒有設法啓動類。

+2

請求時實例化的類有什麼問題?單身人士的廣泛使用將會長期困擾你 – lboshuizen

+0

那些只是每個模塊的服務類別,所以這不是用於這種類型的類別的最小數目。 這裏的問題是在哪裏關閉firtordefualt方法其條件什麼也沒有返回 –

+1

'RuntimeHelpers.RunClassConstructor' – SLaks

回答

1

在對該類進行任何引用之前,可以使用靜態構造函數來運行特定類的代碼。以下是來自MS的一些信息:http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.100).aspx

編輯:Jon Skeet has an article on this subject可能會回答你的問題。它也有代碼示例。

+0

是的但是你必須首先創建該類型的實例以首先激活靜態構造函數,並且MSDN聲明靜態構造函數在創建任何實例之前僅聲明一次,但這並不意味着它將自行執行甚至沒有提到實例 –

+0

靜態構造函數總是被執行,所以啓動你的單例有一個很好的鉤子 – lboshuizen

+0

你能看看代碼並提供示例實例嗎?我沒有創建單例類的問題,但只能自動初始化它們,我測試了靜態構造函數,並且在執行期間靜態構造函數中沒有制動點命中。 –