2011-08-25 30 views
13

Tôi đang sử dụng Autofac để xử lý việc tiêm phụ thuộc trong ứng dụng của mình. Tuy nhiên, tôi có một thành phần thực hiện một số phép thuật phản chiếu trong thời gian chạy và tôi không biết tại thời gian biên dịch những gì phụ thuộc nó sẽ cần.Sử dụng Autofac làm định vị dịch vụ

Thông thường, tôi sẽ chỉ để thành phần này tham chiếu trực tiếp vào Vùng chứa và giải quyết bất cứ thứ gì nó muốn. Tuy nhiên, lớp đang khởi tạo lớp này không có tham chiếu đến Vùng chứa.

Có hiệu quả, thành phần của tôi có phụ thuộc vào Autofac. Tôi thích khớp nối lỏng lẻo hơn, nhưng điều đó dường như không phải là một lựa chọn ở đây. Có cách nào để hỏi (trong constructor args, hoặc sử dụng tiêm tài sản, hoặc bất cứ điều gì!) Autofac để cho tôi một tham chiếu đến các container trong constructor của tôi? Hoặc, có cách nào để có Autofac cung cấp cho tôi một đối tượng định vị dịch vụ ma thuật có thể giải quyết được gì không?

+2

Nó sẽ là thú vị mặc dù để xem những gì "ma thuật" các thành phần đang làm. Có lẽ có nhiều cách khác so với mô hình định vị dịch vụ. Bạn có thể cập nhật bằng một số mã không? –

+0

Tôi có thể mô tả nó khá tốt. Khi thư đến qua một xe buýt, mã xác định loại thư nào đang sử dụng một số siêu dữ liệu và sau đó tạo kiểu được cho biết. Sau đó, nó cần phải tìm tất cả những người triển khai 'IConsume ' (trong đó 'type' là loại từ siêu dữ liệu) bằng cách sử dụng Autofac và sau đó gọi phương thức Consume trên nó. –

+0

Bạn có nghĩa là: http://kozmic.pl/2010/03/11/advanced-castle-windsor-ndash-generic-typed-factories-auto-release-and-more/ –

Trả lời

12

Có, bạn có thể. Chỉ cần tham gia một sự phụ thuộc vào các IComponentContext:

public class MyComponent 
{ 
    IComponentContext _context; 
    public MyComponent(IComponentContext context) 
    { 
     _context = context; 
    } 

    public void DoStuff() 
    { 
     var service = _context.Resolve(...); 
    } 
} 

Update từ nhận xét: các IComponentContext tiêm vào MyComponent phụ thuộc vào phạm vi từ đó MyComponent đã được giải quyết. Do đó, điều quan trọng là phải xem xét phạm vi cuộc sống MyComponent được đăng ký. Ví dụ. sử dụng InstancePerLifetimeScope, ngữ cảnh sẽ luôn phân giải theo cùng phạm vi mà dịch vụ tùy thuộc vào số MyComponent.

+0

Điều này có hoạt động với nhiều phạm vi đời không? tức là IComponentContext có phải là Vùng chứa cơ sở hay phạm vi không? –

+3

Nó sẽ giải quyết 'IComponentContext' từ phạm vi trong đó' MyComponent' đã được giải quyết. Vì vậy, nếu 'MyComponent' được đăng ký là' InstancePerLifetimeScope', 'context' sẽ luôn luôn giải quyết từ phạm vi dự kiến. –

+0

Hoàn hảo, chỉ là những gì tôi cần. –

1

Giả sử bạn có hai thành phần, A và B.

Nếu A cần biết X về B trước khi sử dụng nó, đây là Metadata thẩm vấn và nó được mô tả trong excellent bài này.

Hơn nữa, ngay cả khi bạn không thể điều chỉnh thiết kế của mình cho bài đăng đó, bạn cũng nên cố gắng chắc chắn nếu bạn thực sự cần sử dụng DI Container làm Service Locator.

Tại thời điểm viết bài này, bài đăng trên blog tốt nhất tôi có thể tìm thấy mô tả nó là this một.

+0

Tôi không chắc tại sao bạn trả lời một câu hỏi đã được trả lời đầy đủ với những thứ không liên quan đến câu hỏi của tôi ... như tôi đã nói, vấn đề của tôi không biết "B" nào tôi sẽ cần phải giải quyết cho đến khi thời gian chạy. –

+1

@NikosBaxevanis +1, ngay cả khi OP dường như không nhận được nó. Cả hai bài viết đều xuất sắc.Cụm từ duy nhất này từ bài đăng của Nicholas tiếp tục tất cả: "Đồng thời, thực tế không có lý do gì để sử dụng IContainer hoặc IComponentContext trong các thành phần của bạn nữa". – rsenna

0

Trong các trường hợp khác, khi thành phần của bạn không được tạo bằng cách sử dụng DI, bạn vẫn có thể sử dụng mẫu định vị dịch vụ. Thư viện định vị dịch vụ chung trên CodePlex là hoàn hảo cho mục đích.

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