2010-05-05 8 views
5

Ho una semplice applicazione console in cui ho la seguente configurazione:tipo di nome non utilizzato per l'iniezione costruttore

public interface ILogger 
{ 
    void Log(string message); 
} 

class NullLogger : ILogger 
{ 
    private readonly string version; 

    public NullLogger() 
    { 
     version = "1.0"; 
    } 
    public NullLogger(string v) 
    { 
     version = v; 
    } 
    public void Log(string message) 
    { 
    Console.WriteLine("NULL> " + version + " : " + message); 
    } 
} 

I dettagli di configurazione sono al di sotto:

<type type="UnityConsole.ILogger, UnityConsole" mapTo="UnityConsole.NullLogger, UnityConsole"> 
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration"> 
    <constructor> 
    <param name="message" parameterType="System.String" > 
     <value value="2.0" type="System.String"/> 
    </param> 
    </constructor> 
</typeConfig> 

mio codice chiamante è la seguente:

IUnityContainer container = new UnityContainer(); 
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
section.Containers.Default.Configure(container); 
ILogger nullLogger = container.Resolve<ILogger>(); 
nullLogger.Log("hello"); 

Questo funziona bene, ma una volta che dare un nome a questo tipo qualcosa di simile:

<type type="UnityConsole.ILogger, UnityConsole" mapTo="UnityConsole.NullLogger, UnityConsole" name="NullLogger"> 
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration"> 
    <constructor> 
    <param name="message" parameterType="System.String" > 
     <value value="2.0" type="System.String"/> 
    </param> 
    </constructor> 
</typeConfig> 

Il codice chiamante sopra non funziona, anche se mi registro in modo esplicito il tipo utilizzando

container.RegisterType<ILogger, NullLogger>(); 

Viene visualizzato l'errore:

{"Risoluzione della dipendenza non riuscita, digitare = \" UnityConsole.ILogger \ ", name = \" \ ". Il messaggio di eccezione è: L'operazione di compilazione corrente (chiave di build Key build [UnityConsole.NullLogger, null]) non è riuscita: il parametro v non può essere risolto durante il tentativo di chiamare il costruttore UnityConsole.NullLogger (System.String v). (Strategia tipo BuildPlanStrategy, indice 3) "}

Perché non l'unità sguardo istanze denominate Per farlo funzionare, dovrò fare:?

ILogger nullLogger = container.Resolve<ILogger>("NullLogger"); 

Dove si trova questo comportamento documentato?

Arun

risposta

5

Come sapete - ci sono due tipi di istanze: di nome (può essere molti di loro) e di default (solo uno può essere, e non hanno nomi)

Reso lve() - Non sembra in istanze denominate - sembra per impostazione predefinita solo, e se non v'è alcuna istanza predefinita

  • restituisce un'istanza di T se può essere costruito o
  • un'eccezione se si può' t
    • in caso di interfacce
    • o quando una classe non ha costruttore,
    • o unità non permette di risolvere parametro per di costruzione di questo tipo

Quindi diamo un'occhiata al vostro esempio. Prima domanda, semplice - Perché il codice ha smesso di funzionare quando hai indicato il nome nella configurazione. La risposta è ora che non c'è alcuna istanza predefinita registrata per ILogger e Resolve() - non esamina le istanze denominate - cerca solo il valore predefinito.

Seconda domanda Perché non funziona dopo container.RegisterType<ILogger, NullLogger>(); risposta è siccome l'unità è avido quando si sceglie costruttori per il tipo. Parlando in generale ci vuole sempre il costruttore dove il numero di parametri è più grande. Quindi ci è voluto questo public NullLogger(string v) impossibile creare una stringa (puoi vederla nell'eccezione interna). Non ci sono informazioni su quale costruttore scegliere per la risoluzione predefinita. Tutte le informazioni riguardano il nome. Ed è per questo che

ILogger nullLogger = container.Resolve<ILogger>("NullLogger"); 

opere.

Questo comportamento documentato in help che può essere scaricato da qui http://unity.codeplex.com/releases/view/18855. O potete dare un'occhiata qui http://msdn.microsoft.com/en-us/library/ff649334.aspx

+0

Molto bella spiegazione. Grazie Alex. – Arun

Problemi correlati