2012-01-25 55 views
9

我有一個關於單例模式和MEF的問題。我是實施MEF插件的新手,我還沒有找到答案。C#單例模式和MEF

是否可以通過MEF實現的插件僅提供一個類的實例?

我的老班是這樣的:


    #region Singleton 
    /// 
    /// This class provide a generic and thread-safe interface for Singleton classes. 
    /// 
    /// The specialized singleton which is derived 
    /// from SingletonBase<T> 
    public abstract class Base where T : Base 
    { 
    /* the lock object */ 
    private static object _lock = new object(); 

    /* the static instance */ 
    private static T _instance = null; 
    /// 
    /// Get the unique instance of . 
    /// This property is thread-safe! 
    /// 
    public static T Instance 
    { 
     get 
     { 
     if (_instance == null) 
     { 
      lock (_lock) 
      { 
      if (_instance == null) 
      { 
       /* Create a object without to use new (where you need a public ctor) */ 
       object obj = FormatterServices.GetUninitializedObject(typeof(T)); 
       if (obj != null) // just 4 safety, but i think obj == null shouldn't be possible 
       { 
       /* an extra test of the correct type is redundant, 
       * because we have an uninitialised object of type == typeof(T) */ 
       _instance = obj as T; 
       _instance.Init(); // now the singleton will be initialized 
       } 
      } 
      } 
     } 
     else 
     { 
      _instance.Refresh(); // has only effect if overridden in sub class 
     } 
     return _instance; 
     } 
    } 


    /// 
    /// Called while instantiation of singleton sub-class. 
    /// This could be used to set some default stuff in the singleton. 
    /// 
    protected virtual void Init() 
    { } 

    /// 
    /// If overridden this will called on every request of the Instance but 
    /// the instance was already created. Refresh will not called during 
    /// the first instantiation, for this will call Init. 
    /// 
    protected virtual void Refresh() 
    { } 
    } 
    #endregion 

    #region class 
    public class xy : Base 
    { 
    private bool run; 

    public xy() 
    { 
     this.run = false; 
    } 

    public bool isRunning() 
    { 
     return this.run; 
    } 

    public void start() 
    { 
     // Do some stuff 
     this.run = true; 
    } 
    } 
    #endregion 

有人可以給我一個例子嗎?

+1

可能的重複[MEF是否爲Singleton模式提供任何值?](http://stackoverflow.com/questions/4484619/does-mef-lend-any-value-to-the-singleton-pattern) – IAbstract

+0

對不起,與問題無關,但看起來像是不必要地重新實現了'Lazy '。多餘的代碼行! – binki

回答

18

是的,它是可以這樣做。

默認情況下,MEF將在填充導入時始終返回類的相同實例。所以在技術上你不需要做任何事情,如果你想要它是一個單身人士。這是MEF所稱的共享創建策略。

如果你不想讓你的進口來自同一個實例,你需要指定它,無論是在你的屬性也:

[Import(RequiredCreationPolicy = CreationPolicy.NonShared)] 
public MyClass : IMyInterface 

或者你可以重寫你自己CompositionContainer中,這樣會造成非共享實例默認。

請注意,您也可以明確地指定要共享創建策略(單身):

[Import(RequiredCreationPolicy = CreationPolicy.Shared)] 
public MyClass : IMyInterface 
{ 
    public MyClass() { } // you can have a public ctor, no need to implement the singleton pattern 
} 

但作爲共享(單)已經是默認值時,是沒有必要的。

以下是MEF文檔的鏈接:http://mef.codeplex.com/wikipage?title=Parts%20Lifetime這解釋了我剛剛談到的內容。您也可以通過搜索「MEF創建策略」來查找有關該主題的博客。

+0

謝謝!有用! – subprime

+0

吉爾斯對於MEF在CreationPolicy方面的表現絕對正確。我以爲我會指出,單例模式下的單實例保證在這裏並沒有嚴格執行,因爲有人仍然可以在MEF之外新增另一個實例。 – MatrixManAtYrService

+0

@MatrixManAtYrService好點! – Gilles

1

非常不好的做法!使用靜態構造函數: 保證被執行一次

請注意,您創建的每個T,CLR將複製的靜態數據爲新T

所以你正在創建一個你使用的T類型的單例。

爲單身,最好的辦法是這樣的:

public class Logger { 
    public static readonly Logger Instace; 

    static Logger() { 
     Instace = new Logger(); 
    } 
} 
+0

嗨,謝謝你的回答,但是我怎樣才能在MEF中使用它? – subprime

+0

你可以在MEF中使用它。只要MEF的一切像你通常會,然後當MEF FIRST初始化類靜態構造函數被調用。 –