6

Tôi đã chơi với Unity để hiểu nó nhiều hơn một chút, và đi qua kịch bản sau đây. Nếu tôi đã đăng ký cùng một loại hai lần, nhưng với một là một singleton, làm thế nào tôi có thể gọi Resolve để chỉ singleton được trả lại? Tôi hiểu rằng điều này có thể được thực hiện bằng cách sử dụng Name duy nhất, nhưng tôi tự hỏi liệu điều này có thể được thực hiện mà không có.Hành vi thống nhất để đăng ký cùng một loại hai lần và chỉ giải quyết singleton

Ví dụ:

_container.RegisterType<Music>(new InjectionConstructor(new Album("Non-singleton", "Non-singleton"))); 
_container.RegisterType<Music>(new ContainerControlledLifetimeManager()); 

và gọi

var music = Factory.Resolve<Music>(); 

trả về đối tượng 'Non-singleton'. Lúc đầu, tôi nghĩ rằng nó được dựa trên thứ tự đăng ký, nhưng chuyển đổi xung quanh tôi vẫn nhận được ví dụ 'Không đơn lẻ'.

Có lý do nào cho điều này không? Có cách nào để Resolve chỉ loại singleton cho hai đối tượng đã đăng ký trong cùng một vùng chứa w/out xác định thuộc tính Name?

Trả lời

21

Hãy phá vỡ nó xuống:

_container.RegisterType<Music>(new InjectionConstructor(
    new Album("Non-singleton", "Non-singleton"))); 

này đăng ký với container loại Music không có tên (null hoặc mặc định) và nói với Unity để sử dụng các nhà xây dựng chấp nhận một loại Album. Ngoài ra, để luôn truyền phiên bản được tạo bởi new Album("Non-singleton", "Non-singleton") làm giá trị cho hàm tạo Music(Album album). Vì vậy, mỗi phiên bản Music sẽ có cùng một Album được chèn vào đó.

_container.RegisterType<Music>(new ContainerControlledLifetimeManager()); 

Điều này thực hiện đăng ký dựa trên loại Music không có tên (null hoặc mặc định). Bởi vì, không có InjectionMembers nào chỉ định thay đổi duy nhất cho đăng ký hiện tại là thêm một người quản lý lâu dài. Đăng ký hiện tại được cập nhật vì BuildKey (Type: Music, Name: null) giống nhau cho cả hai cuộc gọi RegisterType.

unityContainer.RegisterType<Music>(new InjectionConstructor(new Album("Non-singleton", "Non-singleton"))); 

unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager()); 

var music = unityContainer.Resolve<Music>(); 
var music2 = unityContainer.Resolve<Music>(); 

bool areEqual = ReferenceEquals(music, music2); 

Ở trên isEqual là đúng, vì vậy một ví dụ được trả về.

Có cách nào để chỉ giải quyết loại singleton cho hai đối tượng đã đăng ký trong cùng một vùng chứa không có chỉ định thuộc tính Tên không?

loại được đăng ký theo loại và Tên nên cách duy nhất để có nhiều đăng ký cho cùng loại là sử dụng một cái tên:

Bây giờ nếu bạn muốn ghi đè lên đăng ký đầu tiên bạn có thể làm bằng cách chỉ định một InjectionConstructor mới. Điều này sẽ xóa kế hoạch xây dựng và thiết lập chính sách lựa chọn hàm tạo.

unityContainer.RegisterType<Music>(new InjectionConstructor(
    new Album("Non-singleton", "Non-singleton"))); 

unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager(), 
    new InjectionConstructor(new Album("singleton", "singleton"))); 

Lưu ý, bạn thường không khó viết mã phụ thuộc (trong trường hợp này là Album) bên trong cuộc gọi loại đăng ký trừ khi nó thực sự là giá trị không đổi. Thậm chí sau đó bạn có thể muốn đăng ký cá thể không đổi như một singleton và để cho container giải quyết nó cho bạn.

Một câu hỏi thú vị là làm cách nào bạn đặt lại chính sách lựa chọn hàm tạo sau cuộc gọi RegisterType đầu tiên để Unity sử dụng chính sách lựa chọn hàm tạo mặc định của nó. Bạn có thể làm điều này với một InjectionMember tùy chỉnh để xóa chính sách lựa chọn hàm tạo:

unityContainer.RegisterType<Music>(new InjectionConstructor(
    new Album("Non-singleton", "Non-singleton"))); 

unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager(), 
    new ClearInjectionConstructor()); 

public class ClearInjectionConstructor : InjectionMember 
{ 
    public override void AddPolicies(Type serviceType, 
     Type implementationType, 
     string name, 
     Microsoft.Practices.ObjectBuilder2.IPolicyList policies) 
    { 
     policies.Clear<IConstructorSelectorPolicy>(
      new NamedTypeBuildKey(implementationType, name)); 
    } 
} 
Các vấn đề liên quan