2011-09-06 36 views
9

Câu hỏi này là theo dõi câu hỏi trước của tôi: Autofac: Hiding multiple contravariant implementations behind one composite.Autofac: Giải quyết các loại biến thể với cả đối số loại trong và ngoài

Tôi đang cố gắng tìm ra những giới hạn của những gì chúng ta có thể làm với sự hỗ trợ hiệp phương sai và đối xứng của Autofac. Tôi nhận thấy rằng ContravariantRegistrationSource của Autofac chỉ hỗ trợ các giao diện chung với một tham số chung duy nhất được đánh dấu bằng từ khóa in. Điều này dường như hạn chế tính hữu ích của tính năng này, và tôi tự hỏi liệu Autofac có những cách khác trong việc mở rộng sự hỗ trợ của hiệp phương sai và contravariance.

Tôi phải thừa nhận rằng tôi không yêu cầu điều này vì thiết kế ứng dụng thực tôi đang làm việc. Tôi đang cố gắng tìm các giới hạn của Autofac vì mục đích giáo dục.

Vì vậy, xem xét các giao diện sau:

public interface IConverter<in TIn, out TOut> 
{ 
    TOut Convert(TIn value); 
} 

Và việc thực hiện sau đây:

public class ObjectToStringConverter : IConverter<object, string> 
{ 
    string IConverter<object, string>.Convert(object value) 
    { 
     return value.ToString(); 
    } 
} 

Và registation sau:

var builder = new ContainerBuilder(); 

builder.RegisterSource(new ContravariantRegistrationSource()); 

builder.RegisterType<ObjectToStringConverter>() 
    .As<IConverter<object, string>>(); 

var container = builder.Build(); 

Với thiết kế này và cấu hình, tôi muốn mong đợi để có thể thực hiện điều này:

// This call succeeds because IConverter<object, string> is 
// explicitly registered. 
container.Resolve<IConverter<object, string>>(); 

// This call fails, although IConverter<string, object> is 
// assignable from IConverter<object, string>. 
container.Resolve<IConverter<string, object>>(); 

Hoặc hãy để tôi đặt nó trừu tượng hơn, với các định nghĩa đưa ra:

public class A { } 
public class B : A { } 
public class C : B { } 

public class AToCConverter : IConverter<A, C> { ... } 

Và việc đăng ký sau:

builder.RegisterType<AToCConverter>() 
    .As<IConverter<C, A>>(); 

tôi mong chờ các cuộc gọi sau để thành công:

container.Resolve<IConverter<C, A>>(); 
container.Resolve<IConverter<B, B>>(); 
container.Resolve<IConverter<A, C>>(); 

Làm cách nào chúng tôi có thể thực hiện việc này với Autofac?

Trả lời

4

Tôi nghĩ đây là giới hạn mà chúng tôi không thể vượt qua trong Autofac, nhưng thật thú vị khi khám phá.

Chúng ta có thể làm 'giải quyết' contravariant bởi vì đưa ra một đối số kiểu chung chung, chúng ta có thể tìm thấy tất cả các kiểu cơ sở/giao diện mà đối số đó sẽ được gán. Tức là, được đưa ra string chúng tôi có thể tìm kiếm các triển khai cho object, IComparable, v.v.

Đi theo hướng ngược lại - từ loại đối số cho tất cả các lớp con của nó - không phải dễ dàng như vậy. Cho object chúng tôi cần một số cách để tìm mọi thứ khác.

Có thể sử dụng kiến ​​thức về các thành phần cụ thể được đăng ký trong vùng chứa, ví dụ: quét tất cả các thành phần tìm kiếm các triển khai có thể và làm việc ngược, nhưng điều này không phải là tuyệt vời cho Autofac bởi vì chúng tôi dựa vào một mô hình 'kéo' để lười biếng tạo ra các thành phần trong nhiều trường hợp.

Hy vọng đây là thực phẩm cho suy nghĩ, quan tâm để xem những gì bạn nghĩ ra.

1

Bạn đúng khi quan sát rằng ContravariantRegistrationSource chỉ nhận dạng các loại có một tham số chung. Nhìn vào the source (hiện tại ở khoảng 166 dòng), bạn sẽ thấy giới hạn đó ngay tại đó. Nhìn vào cách nguồn đăng ký được yêu cầu để cung cấp cho các ứng cử viên có thể tôi có thể hiểu rằng việc nâng giới hạn sẽ đòi hỏi sự phức tạp hơn trong việc thực hiện.

Tôi sẽ nói rằng điều này không chứng minh rằng bạn đã đạt đến giới hạn của Autofac, chỉ giới hạn của nguồn đăng ký cụ thể này. Tôi sẽ để nó như là một bài tập cho người đọc để nâng cao việc thực hiện ContravariantRegistrationSource và tôi chắc chắn rằng dự án Autofac là hạnh phúc hơn để chấp nhận nó trở lại vào lõi.

+0

Kiểm tra tính bình đẳng với 1 là đếm số tham số contravariant; một số tùy ý của các tham số khác (không phải contravariant) vẫn có thể được xử lý. Chúc mừng! –

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