2012-12-07 47 views
6

Với chữ ký constructor sau:Đăng ký loại với Unity sử dụng constructor yêu cầu tham số mảng

public MyClass(Class1 arg1, params Class2[] arg2) 

Làm thế nào tôi có thể đăng ký MyClass với Unity qua trong các loại tên cụ thể sử dụng một InjectionConstructor.

Tôi đã thử những điều sau đây:

unityContainer.RegisterType<IMyClass, MyClass>(new InjectionConstructor(typeof(Class1), new ResolvedParameter<IClass2>("name1"), new ResolvedParameter<IClass2>("name2"))) 

nhưng có được một ngoại lệ nói rằng không có constructor với chữ ký:

public MyClass(Class1 arg1, Class2 arg2, Class2 arg3) 

Tôi đã có vòng vấn đề bằng cách làm quá tải các constructor MyClass. Có cách nào để làm điều này mà không quá tải các nhà xây dựng?

Trả lời

6

Tại sao bạn sẽ thử và sử dụng một số InjectionConstructor ngay từ đầu? Unity biết cách xử lý các mảng ra khỏi hộp.

Từ khóa params chỉ là một số đường cú pháp cho trình biên dịch. Dưới trang bìa args2 chỉ là một mảng đơn giản.

[TestMethod] 
public void TestMethod1() 
{ 
    var container = new UnityContainer(); 
    // if you absolutely have to use an InjectionConstructor this should do the trick 
    // container.RegisterType<IMyClass, MyClass>(
    // new InjectionConstructor(typeof(Class1), typeof(Class2[]))); 
    container.RegisterType<IMyClass, MyClass>(
    new InjectionConstructor(typeof(Class1), typeof(Class2[]))); 
    container.RegisterType<Class2>("1"); 
    container.RegisterType<Class2>("2"); 
    container.RegisterType<Class2>("3"); 
    var myClass = container.Resolve<IMyClass>() as MyClass; 
    Assert.IsNotNull(myClass); 
    Assert.IsNotNull(myClass.Arg2); 
    Assert.AreEqual(3, myClass.Arg2.Length); 
} 

interface IMyClass 
{ 
} 
class MyClass : IMyClass 
{ 
    public Class1 Arg1 { get; set; } 
    public Class2[] Arg2 { get; set; } 
    public MyClass(Class1 arg1, params Class2[] arg2) 
    { 
    Arg1 = arg1; 
    Arg2 = arg2; 
    } 
} 
class Class1 
{ 
} 
class Class2 
{ 
} 

Cập nhật

Nếu bạn chỉ sử dụng một số đăng ký tên bạn sẽ phải sử dụng ResolvedArrayParameter.

container.RegisterType<IMyClass, MyClass>(
    new InjectionConstructor(
    typeof(Class1), 
    new ResolvedArrayParameter<Class2>(
     new ResolvedParameter<Class2>("1"), 
     new ResolvedParameter<Class2>("2")))); 

Brrr! Điều này là siêu xấu xí nhưng nó sẽ giải quyết vấn đề của bạn.

+0

Cảm ơn. Tôi đang sử dụng một constructor tiêm vì tôi có một số triển khai của IClass2 và tôi chỉ đi qua một số người trong số họ để các nhà xây dựng MyClass. Nếu có một cách tốt hơn để làm điều này xin vui lòng cho tôi biết! – macleojw

+0

@macleojw Vui lòng xem cập nhật của tôi. –

1

Kể từ khi nó có vẻ không thích hợp của Class2 'chỉ đơn giản là được niêm yết trực tiếp, là nó có thể thiết lập một cách rõ ràng chúng vào một mảng (và do đó phù hợp với một cách rõ ràng chữ ký constructor của Class1, Class2[]) sẽ làm việc:

unityContainer.RegisterType<IMyClass, MyClass>(new InjectionConstructor(typeof(Class1), new Class2[]{new ResolvedParameter<IClass2>("name1"), new ResolvedParameter<IClass2>("name2")})) 
+0

Tôi e rằng nó không hoạt động vì mảng đang được khai báo kiểu Class2, nhưng các đối tượng đang được khởi tạo với kiểu ResolvedParameter. Nếu tôi loại bỏ các loại đối tượng từ định nghĩa mảng (tức là mới [] {...}) thì nó sẽ tìm kiếm một hàm tạo trong một mảng của ResolvedParameters! – macleojw

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