2015-05-22 23 views
9

Tôi có phương thức mở rộng sau, tồn tại (tự nhiên) trong một lớp tĩnh.Làm thế nào để giải quyết sự phụ thuộc trong lớp tĩnh với Unity?

public static class MyExtensions 
{ 
    [Dependency] 
    private static IMyDataContext _myDataContext { get; set; } 

    public static void MyExtensionMethod(this MyType myType) 
    { 
     // do stuff 

     _myDataContext.DoAwesomeThing(); 
    } 
} 

đối tượng _myDataContextrỗng.

Thông thường tôi muốn sử dụng UnityContainer để đăng ký loại, nhưng vì đây là lớp tĩnh nên tôi không thể.

Tôi cần làm gì để nhanh chóng _ myDataContext sao cho nó không rỗng khi tôi cần?

Trả lời

12

Như bạn đã đề cập, Unity không thể được sử dụng để giải quyết lớp do tĩnh. Có một vài lựa chọn cho việc này. Yêu thích cá nhân của tôi là sử dụng mẫu Abstract Factory. Tôi có xu hướng tinh chỉnh mô hình chỉ một chút để làm việc tốt với DI.

Nhà máy thường loại trông như thế này:

/// <summary> 
/// Creates an IMyDataContext instance 
/// </summary> 
public static class MyDataContextFactory 
{ 
    /// <summary> 
    /// The factory used to create an instance 
    /// </summary> 
    static Func<IMyDataContext> factory; 

    /// <summary> 
    /// Initializes the specified creation factory. 
    /// </summary> 
    /// <param name="creationFactory">The creation factory.</param> 
    public static void SetFactory(Func<IMyDataContext> creationFactory) 
    { 
     factory = creationFactory; 
    } 

    /// <summary> 
    /// Creates a new IMyDataContext instance. 
    /// </summary> 
    /// <returns>Returns an instance of an IMyDataContext </returns> 
    public static IMyDataContext CreateContext() 
    { 
     if (factory == null) throw new InvalidOperationException("You can not create a context without first building the factory."); 

     return factory(); 
    } 
} 

Trong quá trình bootstrap của bạn (có bao giờ bạn thiết lập đăng ký dịch vụ của bạn), bạn có thể khởi tạo các nhà máy để giải quyết sự phụ thuộc của bạn.

MyDataContextFactory.SetFactory(() => this.Container.Resolve<IMyDataContext>()); 

Bây giờ trong phương pháp mở rộng của bạn, bạn tìm nạp ngữ cảnh.

public static class MyExtensions 
{ 
    public static void MyExtensionMethod(this MyType myType) 
    { 
     MyDataContextFactory.CreateContext().DoAwesomeThing(); 
    } 
} 

Đăng ký thống nhất của bạn trong ngữ cảnh, có thể xử lý các cấu hình khác nhau của dịch vụ nếu có điều kiện để giải quyết. Nếu có khả năng rằng bối cảnh có thể được thiết lập bởi một cái gì đó khác hơn là Unity, chủ sở hữu đó có thể chỉ cần vượt qua trong một đại biểu mới mà phương pháp mở rộng sẽ sử dụng.

Tôi có xu hướng tránh tự mình chuyển các thùng chứa vào các nhà máy của tôi, khi bắt đầu leo ​​liên kết chặt chẽ các thùng chứa với ứng dụng của tôi. Nếu tôi sẽ vượt qua bất cứ điều gì trong nhà máy, tôi muốn nó là một đại diện nhà máy được sử dụng để giải quyết thông qua DI, hơn là vượt qua các container DI trong chính nó.

+0

Tôi làm cách nào để thực hiện việc triển khai chung ở trên? Giống như tôi muốn vượt qua bất kỳ giao diện? IMyDataContext có thể là bất kỳ giao diện nào. Bạn có thể cung cấp bất kỳ triển khai nào không? –

+0

Bạn chỉ cần thực hiện các phương thức 'SetContext' và' CreateContext' chung chung. Việc triển khai của bạn sẽ giải quyết '' thay vì 'IDataContext'. Bạn sẽ phải lưu 'Func 'thay vào đó, và sau đó cố gắng đưa nó vào' Func 'khi bạn gọi' CreateContext'. Thành thật mà nói, mặc dù tôi muốn đánh giá bằng cách sử dụng một phương pháp mở rộng mà cần phải trả lại dữ liệu từ một lớp tĩnh như thế này. DI phụ thuộc vào hàm tạo người gọi của bạn, sau đó cung cấp sự phụ thuộc trong lời gọi phương thức mở rộng của bạn làm tham số phương thức. –

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