2012-01-25 38 views
9

Tôi có câu hỏi về Mẫu Singleton và MEF. Tôi mới triển khai Plugin MEF và tôi chưa tìm thấy câu trả lời.C# Mẫu Singleton và MEF

Chỉ có thể cung cấp một phiên bản của một lớp thông qua một Plugin được triển khai MEF?

lớp cũ của tôi là một cái gì đó như thế này:


    #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 

Ai đó có thể cung cấp cho tôi một ví dụ?

+1

bản sao có thể có của [Có MEF cho vay bất kỳ giá trị nào đối với mẫu Singleton không?] (Http://stackoverflow.com/questions/4484619/does-mef-lend-any-value-to-the-singleton-pattern) – IAbstract

+0

Xin lỗi, không liên quan đến câu hỏi, nhưng có vẻ như bạn đang thực hiện lại một cách không cần thiết 'Lazy '. Các dòng mã không liên quan! – binki

Trả lời

18

Có nó có thể làm như vậy.

Theo mặc định, MEF sẽ luôn trả về cùng một phiên bản của một lớp khi điền vào hàng nhập của bạn. Vì vậy, về mặt kỹ thuật, bạn không phải làm bất cứ điều gì nếu bạn muốn nó là một singleton. Đây là những gì MEF gọi là Chính sách tạo chia sẻ.

Nếu bạn không muốn nhập khẩu của bạn đến từ cùng một ví dụ, bạn cần phải xác định nó, hoặc trong các thuộc tính của bạn tương tự như vậy:

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

Hoặc bạn có thể ghi đè lên CompositionContainer riêng của bạn do đó sẽ tạo ra trường hợp NonShared theo mặc định.

Lưu ý rằng bạn cũng có thể chỉ định rõ ràng rằng bạn muốn có một chính sách chung Creation (độc thân):

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

Nhưng nó không phải là cần thiết như Shared (singleton) đã là giá trị mặc định.

Đây là liên kết đến tài liệu của MEF: http://mef.codeplex.com/wikipage?title=Parts%20Lifetime giải thích những gì tôi vừa nói đến. Bạn cũng có thể tìm các blog về chủ đề bằng cách tìm kiếm: "Chính sách tạo MEF".

+0

cảm ơn! Nó hoạt động! – subprime

+0

Gilles hoàn toàn đúng về cách thức mà MEF sẽ xử lý đối với CreationPolicy. Chỉ cần nghĩ rằng tôi muốn chỉ ra rằng bảo đảm một ví dụ mà bạn nhận được với mẫu đơn không được thực thi nghiêm ngặt ở đây vì ai đó vẫn có thể tạo ra một ví dụ khác ngoài MEF. – MatrixManAtYrService

+0

@MatrixManAtYrService điểm tốt! – Gilles

1

Thực hành rất xấu! sử dụng hàm tạo static: đảm bảo được thực thi chính xác sau khi

Xin lưu ý rằng đối với mỗi T mà bạn tạo, CLR sẽ sao chép dữ liệu tĩnh cho T mới.

Vì vậy, bạn đang tạo một singleton cho mỗi loại T mà bạn sử dụng.

Cách tốt nhất cho singleton là một cái gì đó như thế này:

public class Logger { 
    public static readonly Logger Instace; 

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

Hi, cảm ơn cho câu trả lời rất quikly nhưng làm thế nào tôi có thể sử dụng nó với MEF? – subprime

+0

Bạn có thể sử dụng tính năng này với MEF. Chỉ cần MEF tất cả mọi thứ như bạn thường làm và sau đó khi MEF FIRST khởi tạo lớp, hàm tạo tĩnh được gọi. –

Các vấn đề liên quan