2013-03-08 33 views
12

ho una classe di interfaccia:Ninject legano tutte le classi che implementano la stessa interfaccia

public interface IStartUpTask 
{ 
    bool IsEnabled { get; } 
    void Configure(); 
} 

Ho classi multimple di attuazione della stessa interfaccia

Una delle classi si presenta così:

public class Log4NetStartUpTask : IStartUpTask 
{ 
    public bool IsEnabled { get { return true; } } 

    public void Configure() 
    { 
     string log4netConfigFilePath = ConfigurationManager.AppSettings["log4netConfigFilePath"]; 
     if (log4netConfigFilePath == null) 
      throw new Exception("log4netConfigFilePath configuration is missing"); 

     if (File.Exists(log4netConfigFilePath) == false) 
      throw new Exception("Log4Net configuration file was not found"); 

     log4net.Config.XmlConfigurator.Configure(
      new System.IO.FileInfo(log4netConfigFilePath)); 
    } 
} 

Come posso dire a Ninject che voglio che tutte le classi implementino lo IStartUpTask per collegarsi automaticamente a se stessi?

Ho trovato un esempio utilizzando StructureMap che esegue questa operazione, ma non so come farlo in Ninject.

Scan(x => { 
    x.AssemblyContainingType<IStartUpTask>(); 
    x.AddAllTypesOf<IStartUpTask>(); 
    x.WithDefaultConventions(); 
}); 

risposta

12

Come posso dire Ninject che voglio tutte le classi attuazione del IStartUpTask per collegarsi automaticamente a se stessi?

Prima di tutto, lascia che ti dica che Ninject lega automaticamente tutte le classi automaticamente. Non devi fare nulla di speciale per quello.

Detto questo, capisco che potresti volere il binding esplicito se vuoi cambiare scope o allegare nomi o metadati. In questo caso la lettura.

Non so se è possibile eseguire ciò che si è dopo in vanilla ninject, ma è possibile utilizzare ninject.extensions.conventions. Usando questa libreria puoi scrivere:

Kernel.Bind(x => 
    x.FromThisAssembly() 
    .SelectAllClasses() 
    .InheritedFrom<IStartUpTask>() 
    .BindToSelf()); 
+2

Questo tipo di ha funzionato per me, ma dovevo fare "BindSingleInterface" e non BindToSelf. Ma non importa, il trucco per me era il bit "InheritedFrom". Grazie! – noocyte

+0

Ho trovato questa soluzione, ma in qualche modo "non ha funzionato" per me. Mi ci è voluto un po 'per capire perché, quindi lo aggiungo qui per aggiungere più contesto. Per impostazione predefinita, Ninject associa solo le classi pubbliche, è necessario chiamare il metodo 'IncludingNonePublicTypes()' se si desidera associare le classi interne. – mivra

2

si può chiamare esplicitamente nel codice:

... 
Bind<IStartUpTask>().To<Log4NetStartUpTask>(); 
Bind<IStartUpTask>().To<SomeOtherStartUpTask>(); 
... 

utilizzarlo in SomeClass

public class SomeClass 
{ 
    private readonly List<IStartUpTask> startUpTaskList; 

    public SomeClass(IEnumerable<IStartUpTask> startUpTaskList) 
    { 
     this.startUpTaskList = startUpTaskList; 
    } 

    foreach (var startUpTask in this.startUpTaskList) 
    { 
     ... 
    } 
} 
+0

L'ultima rilegatura non sovrascriverà quelle precedenti? – Catalin

+0

@MikroDel: così nel tuo esempio, quale classe verrà iniettata quando è necessaria l'interfaccia IStartUpTask? Questo sembra sbagliato. –

+0

@RaraituL Ho aggiornato la mia risposta per rendere più semplice la comprensione di – MikroDel

Problemi correlati