2009-03-13 21 views
13

Tôi vẫn còn khá mới để sử dụng Autofac và một điều tôi bỏ lỡ trong tài liệu và ví dụ là làm thế nào để làm cho nó dễ dàng để có được container cấu hình từ những nơi khác nhau trong một ứng dụng web.Tự động điền trong các ứng dụng web, nơi tôi nên lưu trữ vùng chứa để dễ dàng truy cập?

Tôi biết tôi có thể sử dụng nhà máy điều khiển Autofac để tự động giải quyết các phụ thuộc của bộ xây dựng cho bộ điều khiển, nhưng bạn có thể giải quyết những thứ khác mà bạn chưa giải quyết.

Có một mô hình rõ ràng mà tôi không biết về điều này không?

Cảm ơn bạn!

+4

BTW câu hỏi này được hỏi khi MVC ở phiên bản 2. Trong MVC 3, 'DependencyResolver.Current' là tất cả những gì bạn cần cho dù bạn đang sử dụng Autofac hay cái gì khác. –

Trả lời

11

Trước hết hãy cố gắng không sử dụng quá mức container IoC. Nó tuyệt vời cho bộ điều khiển "dây lên", quan điểm và dịch vụ nhưng các đối tượng cần được tạo trong thời gian chạy nên được tạo bởi các đối tượng nhà máy chứ không phải bởi vùng chứa. Nếu không, bạn nhận được Container.Resolve gọi tất cả thông qua mã của bạn, buộc nó vào container của bạn. Những phụ thuộc phụ này đánh bại mục đích của việc sử dụng IoC. Trong hầu hết các trường hợp, tôi có thể nhận được bằng cách chỉ giải quyết một hoặc hai phụ thuộc ở cấp cao nhất trong đơn đăng ký của tôi. Các container IoC sau đó sẽ đệ quy giải quyết hầu hết các phụ thuộc.

Khi tôi cần vùng chứa ở nơi khác trong chương trình của tôi, đây là mẹo tôi thường sử dụng.

public class Container : IContainer 
{ 
    readonly IWindsorContainer container; 

    public Container() 
    { 
     // Initialize container 
     container = new WindsorContainer(new XmlInterpreter(new FileResource("castle.xml"))); 

     // Register yourself 
     container.Kernel.AddComponentInstance<IContainer>(this); 
    } 

    public T Resolve<T>() 
    { 
     return container.Resolve<T>(); 
    } 
} 

Tôi bọc vật chứa trong một lớp Container như thế này. Nó thêm chính nó vào thùng chứa bọc trong constructor. Bây giờ các lớp học cần container có thể có một IContainer tiêm. (ví dụ là cho Castle Windsor nhưng có thể có thể được điều chỉnh cho AutoFac)

1

Cách thông thường để thực hiện việc này là lưu trữ vùng chứa trong biến tĩnh trong lớp Ứng dụng toàn cầu của bạn.

+2

Ah, nhưng hãy cẩn thận mà bạn lưu trữ container! Bạn không wnat container ứng dụng, đó là chắc chắn! – n8wrl

30

Cách "Autofac" là có tham số khởi tạo IContext. Autofac sẽ tiêm một đối tượng có thể được sử dụng để giải quyết các loại.

Ngữ cảnh thường là vùng chứa đằng sau hậu trường, IContainer triển khai giao diện IContext, mặc dù IContext bị giới hạn chỉ thực hiện các giải pháp.

Tôi biết rằng vùng chứa không được "lạm dụng", nhưng tôi có, như OP, các lớp yêu cầu giải quyết các loại không được biết trước (và do đó không thể được sử dụng làm tham số hàm tạo). Tôi thấy nó hữu ích trong những trường hợp này, để nghĩ về container như một dịch vụ khác có thể được sử dụng để giải quyết các dịch vụ khác và tiêm giống như bất kỳ dịch vụ nào khác.

Nếu bạn cảm thấy rằng việc sử dụng IContext liên kết bạn với Autofac và bạn cần trừu tượng hóa bằng giao diện của riêng bạn, đây chỉ là vấn đề đăng ký lớp bao bọc IContext với vùng chứa của bạn.

Cập nhật: trong Autofac 2, IContext được gọi là IComponentContext.

+0

Tại sao không tiêm nhà máy thay thế? – TrueWill

+0

@TrueWill - ... và sự khác biệt là gì? –

+0

Một lần nữa, đầu mối ở đây là không phải luôn luôn (và đặc biệt là với mã di sản không được xây dựng với DI trong tâm trí) là các loại dịch vụ cần thiết không được biết đến tại thời gian biên dịch. Do đó, nhà máy được nhập "không mạnh" là bắt buộc. IContext chỉ là, một nhà máy có thể sản xuất các thể hiện của các loại mà một người cố gắng giải quyết. –

6

Phản hồi của Peter Lillevold ở trên là chính xác - bạn có thể truy cập vùng chứa từ bất kỳ thành phần nào bằng cách phụ thuộc vào giao diện IContext.

Nếu bạn thực sự cần tham chiếu vùng chứa thực tế, hãy xem Autofac.Integration.Web.IContainerProviderAccessor.

8

Việc chứa IOC trên toàn cầu không phải là phương pháp hay nhất. Ngay cả passing container is not encouraged.

Nếu dependency injection không thể được sử dụng (bạn cần phải tạo các đối tượng \ yêu cầu sau khi thành phần đã được tạo ra) sau đó bạn có thể:

  1. Sử dụng nhà máy tay mã (nhà máy được tiêm với thành phần và thành phần sử dụng nhà máy để tạo các vật thể khác)
  2. Sử dụng Autofac delegate factories hoặc new auto-generated factories in Autofac 2.
+0

huzzah vì không sử dụng vùng chứa làm định vị dịch vụ – JJS

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