2012-12-07 12 views
6

Dato il seguente firma costruttore:tipo Registrati con l'Unità di usare costruttore richiede parametro array

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

Come posso registrare MyClass con Unity passando in specifici tipi di nome utilizzando un InjectionConstructor.

ho provato la seguente:

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

ma ottenere un'eccezione dicendo che non v'è alcun costruttore con firma:

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

ho saggiato il problema sovraccaricare il costruttore di MyClass. C'è un modo per farlo senza sovraccaricare il costruttore?

risposta

6

Perché dovresti provare a utilizzare uno InjectionConstructor in primo luogo? Unity sa come gestire gli array fuori dalla scatola.

La parola chiave params è solo un po 'di zucchero sintattico per il compilatore. Sotto la copertina args2 c'è solo un semplice array.

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

Aggiornamento

Se si sta utilizzando solo alcune delle registrazioni di nome si dovrà utilizzare il ResolvedArrayParameter.

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

Brrr! Questo è super brutto ma dovrebbe risolvere il tuo problema.

+0

Grazie. Sto usando un costruttore di iniezioni perché ho diverse implementazioni di IClass2 e sto passando solo alcune di esse al costruttore MyClass. Se c'è un modo migliore per farlo, per favore dimmelo! – macleojw

+0

@macleojw Si prega di consultare il mio aggiornamento. –

1

Poiché sembra a non gradire le istanze della 'Class2' semplicemente essere elencati direttamente, è possibile che impostandole in modo esplicito in un array (e quindi di corrispondenza esplicitamente la firma costruttore Class1, Class2[]) avrebbe funzionato:

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

Ho paura che non funzioni perché l'array viene dichiarato di tipo Class2, ma gli oggetti con cui viene inizializzato sono di tipo ResolvedParameter. Se rimuovo il tipo di oggetto dalla definizione dell'array (cioè nuovo [] {...}), allora cerco un costruttore che assuma una serie di ResolvedParameters! – macleojw

Problemi correlati