2012-01-24 30 views
12

Autofac có mô-đun, Windsor có Trình cài đặt và Sơ đồ Cấu trúc Bản đồ ... với Injector Đơn giản Làm thế nào tôi có thể đóng gói cấu hình logic vào các lớp tái sử dụng?Làm thế nào tôi có thể mô phỏng Mô-đun/Trình cài đặt/Đăng ký với Đầu vào Đơn giản

Tôi đã thử:

public interface IModule { } 

public class FooModule : IModule 
{ 
    public FooModule(SimpleInjector.Container container) 
    { 
     container.RegisterSingleton<IBar, Bar>(); 
     container.RegisterSingleton<IFoo, Foo>(); 
    } 
} 

Và tôi sử dụng nó trong Root Thành phần:

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 
    container.RegisterCollection<IModule>(new FooModule(container)); 
    ... 
} 

Tuy nhiên, FooModule phụ thuộc vào thùng chứa và có thể ở không phải là một thực hành tốt ... thấy http://code.google.com/p/autofac/wiki/BestPractices :

Nếu các thành phần có phụ thuộc vào vùng chứa, hãy xem cách họ đang sử dụng vùng chứa để truy xuất dịch vụ và thêm các dịch vụ đó vào các đối số của hàm tạo (phụ thuộc được tiêm) của thành phần thay thế.

+0

Lưu ý rằng, ngay cả với Autofac- 'FooModule' của bạn sẽ phụ thuộc vào vùng chứa (hoặc với Autofac,' ContainerBuilder, vì Autofac chia thùng chứa thành hai loại). Hãy xem [tài liệu Autofac này] (http://code.google.com/p/autofac/wiki/StructuringWithModules) và bạn sẽ thấy rõ rằng các mô-đun có sự phụ thuộc này. Đối với một mô-đun, bạn chỉ cần chứa vùng chứa, nhưng điều đó không quan trọng vì một mô-đun sẽ là một phần của gốc thành phần của bạn. – Steven

Trả lời

14

Tính năng 'mô-đun' được cố ý rời khỏi thư viện lõi đơn giản, nhưng có một số SimpleInjector.Packaging NuGet package cho phép bạn thực hiện việc này. 'Gói' là thuật ngữ Simple Injector sử dụng. Thư viện này tuy nhiên, không có gì hơn một giao diện IPackage và hai phương pháp mở rộng. Bạn có thể đạt được như vậy bằng cách viết code như thế này:

Một gói:

public static class BootstrapperPackage 
{ 
    public static void RegisterServices(Container container) 
    { 
     container.Register<IBar, Bar>(Lifestyle.Scoped); 
     container.Register<IFoo, Foo>(Lifestyle.Singleton);    
    } 
} 

Trong gốc thành phần của bạn:

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 

    BootstrapperPackage.RegisterServices(container); 

    ... 
} 

Sự khác biệt với các SimpleInjector.Packaging NuGet package là gói này định nghĩa một giao diện cho bạn và cho phép bạn tải động nhiều gói trong một dòng:

public class BusinessLayerPackage : IPackage 
{ 
    public void RegisterServices(Container container) 
    { 
     container.Register<IBar, Bar>(Lifestyle.Scoped); 
     container.Register<IFoo, Foo>(Lifestyle.Singleton);    
    } 
} 

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 

    container.RegisterPackages(AppDomain.CurrentDomain.GetAssemblies()); 
} 

Tuy nhiên, nếu bạn không thực sự cần nạp năng động, sử dụng phương pháp tĩnh (như hình trên) được ưa thích, bởi vì nó có những ưu điểm sau:

  • Làm tải module rất rõ ràng và có thể phát hiện.
  • Giúp dễ dàng chọn mô-đun nào cần tải và mô-đun nào không tải.
  • Giúp bạn dễ dàng chuyển các giá trị thừa sang phương thức RegisterServices, chẳng hạn như giá trị cấu hình mà mô-đun đó yêu cầu. Điều này ngăn cản các mô-đun lấy một sự phụ thuộc cứng trên hệ thống cấu hình.

Để biết thêm thông tin, vui lòng đọc this.

+0

Cảm ơn Steven, ... nhưng có đúng không khi chuyển container đến các lớp khác? – o3o

+0

Không, nhưng mô-đun không phải là một phần của mã ứng dụng, mà là một phần của [thành phần gốc] (http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx), làm cho nó trở thành một thành phần cơ sở hạ tầng. Bạn có thể sử dụng vùng chứa bên trong các thành phần cơ sở hạ tầng của mình. Mark Seemann mô tả điều này rõ ràng [ở đây] (http://blog.ploeh.dk/2011/08/25/ServiceLocatorRolesVsMechanics.aspx). – Steven

+1

Tại sao tính năng này bị bỏ sót khỏi thư viện cốt lõi? – Sam

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