2012-12-07 21 views
6

を必要とするコンストラクタを使用します登録型は、次のコンストラクタシグネチャを与えられたパラメータ配列

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

は、どのように私はUnityがInjectionConstructorを使用して、特定の名前付きの型を渡すとのMyClassを登録することができます。

私は次のことを試してみた:

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

が、署名付きコンストラクタが存在しないことを言った例外を取得:

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

私はMyClassのコンストラクタをオーバーロードすることで、問題の周りを持っているが。コンストラクタをオーバーロードしないでこれを行う方法はありますか?それは単に直接列挙されている「クラス2」のインスタンスを嫌うと思われるので

答えて

6

最初にInjectionConstructorを試してみましょう。 Unityは、箱からすぐに配列を扱う方法を知っています。

キーワードparamsは、コンパイラの文法上の砂糖です。カバーの下にargs2は単なる配列です。

[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 
{ 
} 

更新

あなただけがResolvedArrayParameterを使用する必要がありますという名前の登録の一部を使用している場合。

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

Brrr!これは超醜いですが、あなたの問題を解決するはずです。

+0

ありがとうございます。 IClass2の実装がいくつかあり、そのうちのいくつかをMyClassコンストラクタに渡すだけなので、私は注入コンストラクタを使用しています。これを行うより良い方法があれば教えてください! – macleojw

+0

@macleojw私の更新をご覧ください。 –

1

、それが明示的配列にそれらを設定する(したがって、明示的Class1, Class2[]のコンストラクタシグネチャに一致)がうまくいく可能性がある:

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

配列がClass2型として宣言されているため、初期化されているオブジェクトの型がResolvedParameterであるため、動作しないのは恐れています。配列の定義(つまり、new [] {...})からオブジェクト型を削除すると、ResolvedParametersの配列を取り込むコンストラクタが検索されます。 – macleojw

関連する問題