2009-07-31 35 views
5

có thể không nhận được đầu của tôi quanh tham số đi qua trong Autofac, đoạn code sau không làm việc:Autofac qua tham số và autowiring

class Config { 
    public Config(IDictionary<string, string> conf) {} 
} 

class Consumer { 
    public Consumer(Config config) {} 
} 

void Main() 
{ 
    var builder = new Autofac.Builder.ContainerBuilder(); 
    builder.Register<Config>(); 
    builder.Register<Consumer>(); 
    using(var container = builder.Build()){ 
     IDictionary<string,string> parameters = new Dictionary<string,string>(); 
     var consumer = container.Resolve<Consumer>(Autofac.TypedParameter.From(parameters)); 
    } 
} 

mà ném:

DependencyResolutionException: The component 'UserQuery+Config' has no resolvable constructors. Unsuitable constructors included: 
Void .ctor(System.Collections.Generic.IDictionary`2[System.String,System.String]): parameter 'conf' of type 'System.Collections.Generic.IDictionary`2[System.String,System.String]' is not resolvable. 

nhưng đoạn mã sau hiện hoạt động:

IDictionary<string,string> parameters = new Dictionary<string,string>(); 
var config = container.Resolve<Config>(Autofac.TypedParameter.From(parameters)); 
var consumer = container.Resolve<Consumer>(Autofac.TypedParameter.From(config)); 
+2

Câu hỏi của bạn không rõ ràng. Vì lợi ích của những người không phải là người dùng autofac, bạn có thể hiển thị các khai báo của p, config, TypedParameter.From và container.Resolve không? Ngoài ra, xin vui lòng ghi rõ trong cách nó "không hoạt động" - biên dịch lỗi thời gian? Ngoại lệ? –

+0

được làm rõ bằng một ví dụ có thể chạy được trong ví dụ. LINQPad (tham khảo Autofac.dll) –

Trả lời

18

Lặp đi lặp lại ở đây câu trả lời từ Autofac mailing list:

Các thông số thông qua để giải quyết chỉ liên quan đến đơn vị thực hiện trực tiếp của các dịch vụ mà bạn đang giải quyết, vì vậy thông qua các thông số cấu hình để quyết tâm gọi cho won tiêu dùng 't làm việc. Các khoảng cách này là thay đổi đăng ký tiêu dùng của bạn để:

builder.Register((c, p) => new Consumer(c.Resolve<Config>(p))); 
+0

tôi đoán ý của bạn là: builder.Register ((c, p) => new Consumer (c.Giải quyết (p))); bởi vì nó hoạt động perfetct! Cảm ơn Nicholas! –

+3

+1 cuối cùng ai đó biết autofac :-) – galaktor

+4

Bởi "cuối cùng ai đó biết autofac" bạn có nghĩa là tác giả, yeah chắc chắn :) – uriDium

0

Autofac rõ ràng đang cố gắng giải quyết đã tham số của lớp Config của bạn với giả định rằng chính từ điển là một kiểu có thể phân giải được. Tôi không biết cú pháp autofac về cách thực hiện nó. Nhưng bạn có thể cần thực hiện thêm các bước khi đăng ký loại Config, e. g. trao cho nó một đại biểu đi qua một từ điển mới.

+0

bạn đã đúng! nhưng sau đó vấn đề tiếp theo phát sinh, nếu tôi đăng ký Config như sau để thay thế: builder.Register ((c, p) => new Config (p.TypedAs >())); p trống vào thời gian giải quyết! –

+0

Hm. Có lẽ đó là bởi vì bạn cung cấp cho autofac một đại biểu, nhưng sau đó các đại biểu vẫn không có từ điển tại thời gian chạy. Hãy thử thực sự cung cấp một từ điển mới trong đại biểu của bạn, một cái gì đó như thế này (nhận thức được, tôi vẫn không biết chính xác diễn đàn cho autofac): builder.Register ((c) => new Config (new Dictionary ())); – galaktor

+0

không phải lúc nào cũng cung cấp cho Config một từ điển trống? mặc dù các đối số nào được truyền vào thời gian giải quyết? –

0

Thật không may, container IoC như Autofac không được trang bị với một "mô-đun xin vui lòng đọc tâm trí của tôi".

Điều bạn đang cố gắng thực hiện là "Tôi biết một trong các loại có liên quan ở đây cần từ điển và tôi cần dịch vụ kiểu Người tiêu dùng, bạn có thể thử tìm hiểu xem lấy và chỉ cần làm điều đúng? ".

Nếu bạn giải quyết một dịch vụ và chỉ định tham số, thông số đó sẽ được cố gắng sử dụng cho dịch vụ cụ thể đó. Vùng chứa sẽ không cố gắng truyền bá giá trị tham số đó đến bất kỳ phụ thuộc nào.

+0

chắc chắn, nỗ lực đầu tiên của tôi là ngây thơ, nhưng không cách ra, nếu các tham số đã được treaded như đăng ký nó đã hoạt động? –

+0

Có thể, sau đó AutoFac sẽ có thể tìm ra, nhưng bạn cần phải đăng ký trước các tham số như các dịch vụ với AutoFac. Cá nhân tôi không đề xuất các dịch vụ với các tham số constructor, nó luôn là một dịch vụ bị rò rỉ vì nó rò rỉ các chi tiết triển khai vào mã sử dụng nó, làm cho việc thay thế dịch vụ trở nên khó khăn hơn. Hãy xem xét như một ví dụ một dịch vụ mà bạn sẽ chuyển một tên tập tin cấu hình cho nó, sau đó nếu sau này bạn quyết định sử dụng một dịch vụ đọc cấu hình từ một cơ sở dữ liệu thay thế? –

+0

vâng tôi biết, giải pháp của tôi không phải là điểm trên nhưng điều là, tôi muốn người dùng có thể cấu hình loại dịch vụ được sử dụng. Nhưng dịch vụ đó cũng cần cấu hình khác nhau, vì vậy bây giờ các cấu hình dịch vụ này được truyền vào dưới dạng IDictionary .. tôi sẽ yêu các giải pháp tốt hơn cho nó, nhưng điều này thực sự là nỗ lực tốt nhất của tôi cho đến nay .. –

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