2010-05-11 18 views
57

Tôi bắt đầu thực hiện nhiều công việc hơn với Unity. Tôi nhận thấy rằng phương pháp Resolver có tham số tham sốResolverOverride.Unity 2.0: Cách sử dụng Resolve với ResolverOverride?

Ai đó có thể cho tôi ví dụ về cách tôi có thể sử dụng ResolverOverride hoặc chỉ cho tôi một số nguồn khác mà tôi có thể nhận được nhiều manh mối hơn.

Trả lời

92

Như bạn đã nhận thấy đây là một (Tính năng và thực sự mát mẻ) mới của Unity 2. Tính năng này cho phép bạn

  • thông số vượt qua để xây dựng trong thời điểm này khi bạn giải quyết các lớp. Trong hiệp 1, bạn có thể thiết lập chỉ có một giá trị trong thời điểm này khi bạn đăng ký loại qua InjectionConstructor mới (...)

ParameterOverride : ResolverOverride

lớp

Một ResolverOverride cho phép bạn ghi đè lên một tham số có tên được chuyển đến một hàm tạo .

  • tương tự cho phụ thuộc với DependencyOverride : ResolverOverride

Một lớp học đó sẽ ghi đè giá trị tiêm bất cứ khi nào có một sự phụ thuộc của loại nhất định, không phân biệt nơi nó xuất hiện trong đối tượng đồ thị.

  • tương tự cho các thuộc tính với PropertyOverride : ResolverOverride

Một ResolverOverride cho phép bạn ghi đè giá trị cho một tài sản cụ thể.

Ví dụ

using System; 
using Microsoft.Practices.Unity; 

namespace ConsoleApplication1 { 
    class Program { 
     static void Main(string[] args) { 

      var container = new UnityContainer(); 

      //ParameterOverride example 

      container.RegisterType<IConcreteService, ConcreteService>(
       new InjectionConstructor(7) //Old way to pass value to constructor - not flexible. 
              //All resolved (without ovverride wich aapears only in unity 2.0) classes will hav val=7 
       ); 

      var service0 = container.Resolve<IConcreteService>(); 
      Console.WriteLine(service0.Val); //prints 7 

      var service = container.Resolve<IConcreteService>(new ParameterOverride("val", 3)); 
      Console.WriteLine(service.Val); // prints 3 

      var service2 = container.Resolve<IConcreteService>(new ParameterOverride("val", 5)); 
      Console.WriteLine(service2.Val); // prints 5 

      Console.ReadLine(); 

      //DependencyOverride example 

      var b0 = container.Resolve<B>(new DependencyOverride<IConcreteService>(new ConcreteService(42))); 
      Console.WriteLine(b0.Service.Val); //print 42 
      Console.WriteLine(b0.Service1.Val); //print 42 

      var b = container.Resolve<B>(new DependencyOverride<IConcreteService>(new ConcreteService(-42))); 
      Console.WriteLine(b.Service.Val); // print -42 
      Console.WriteLine(b.Service1.Val); // print -42 

      Console.ReadLine(); 

      //PropertyOverride example 

      var b1 = container.Resolve<B>(new PropertyOverride("Service", new ConcreteService(42)), 
       new PropertyOverride("Service1", new ConcreteService(-42))); 
      Console.WriteLine(b1.Service.Val); //print 42 
      Console.WriteLine(b1.Service1.Val); //print -42 

      Console.ReadLine(); 



     } 
    } 

    public interface IConcreteService { 
     int Val { get; set; } 
    } 
    public class ConcreteService : IConcreteService { 

     public int Val { get; set; } 

     public ConcreteService(int val) { 
      Val = val; 
     } 
    } 

    public class B { 
     [Dependency] 
     public IConcreteService Service{ get; set; } 

     [Dependency] 
     public IConcreteService Service1 { get; set; } 

    } 
} 

Không có ý tưởng tại sao google giữ im lặng về điều đó.

Trích dẫn từ tài liệu XML mã nguồn Unity.

+1

Cảm ơn câu trả lời tuyệt vời. +1 – Vadim

+0

Đây là một trợ giúp tuyệt vời. Rất tốt giải thích. –

+1

+1 Giải thích hoàn hảo! –

43

Chỉ trong trường hợp ai đó quan tâm, tôi đã thực hiện một phương pháp mở rộng làm cho cú pháp để giải quyết bằng cách sử dụng ParameterOverride dễ đọc hơn một chút. Phương pháp này là như sau:

public static class UnityExtensions 
{ 
    public static T Resolve<T>(this IUnityContainer container, object parameterOverrides) 
    { 
     var properties = parameterOverrides 
      .GetType() 
      .GetProperties(BindingFlags.Public | BindingFlags.Instance); 
     var overridesArray = properties 
      .Select(p => new ParameterOverride(p.Name, p.GetValue(parameterOverrides, null))) 
      .Cast<ResolverOverride>() 
      .ToArray(); 
     return container.Resolve<T>(null, overridesArray); //null needed to avoid a StackOverflow :) 
    } 
} 

Với điều này, bạn có thể viết lại ví dụ ParameterOverride như sau:

var service = container.Resolve<IConcreteService>(new {val=3}); 

Tôi hy vọng điều này rất hữu ích cho ai đó ...

+0

Cách thanh lịch để ghi đè thông số, cảm ơn bạn! –

+0

Tôi đồng ý - +1 phiếu bầu cho điều này. – TravisWhidden

+0

Công việc hay. 1 phiếu bầu cho số – Spock

13

Chỉ cần thêm của tôi 2c.Bạn chỉ có thể thêm một ParameterOverrides như vậy:

Container.Resolve<IConcreteService>(new ParameterOverrides 
{                     
    {"val", 42} 
}); 
Các vấn đề liên quan