2013-03-08 12 views
12

ich eine Schnittstelle Klasse:ninject alle Klassen binden die gleiche Schnittstelle implementieren

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

I multimple Klassen die gleiche Schnittstelle

Eine der Klassen sieht wie folgt aus der Umsetzung:

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)); 
    } 
} 

Wie kann ich Ninject sagen, dass ich möchte, dass alle Klassen, die IStartUpTask implementieren, automatisch an sich binden?

Ich habe ein Beispiel mit Structuremap gefunden, das dies tut, aber ich weiß nicht, wie man es in Ninject macht.

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

Antwort

12

Wie kann ich Ninject sagen, dass ich möchte, dass alle Klassen die Umsetzung IStartUpTask automatisch an sich binden?

Zunächst möchte ich Ihnen sagen, dass Ninject automatisch alle Klassen an sich bindet. Sie müssen nichts Besonderes dafür tun.

Nachdem ich das gesagt habe, verstehe ich, dass Sie die explizite Bindung wünschen, wenn Sie den Bereich ändern oder Namen oder Metadaten anhängen möchten. In diesem Fall lesen Sie weiter.

Ich weiß nicht, ob es möglich ist, was Sie in Vanille Ninject tun, aber Sie können ninject.extensions.conventions verwenden. Mit dieser Bibliothek können Sie schreiben:

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

Diese Art von arbeitete für mich, aber ich musste 'BindSingleInterface' tun und nicht BindToSelf. Aber egal, der Trick für mich waren die 'InheritedFrom'-Bits. Danke! – noocyte

+0

Ich fand diese Lösung, aber es hat irgendwie "nicht funktioniert" für mich. Es hat eine Weile gedauert, bis ich herausgefunden habe, warum. Daher füge ich es hier hinzu, um mehr Kontext hinzuzufügen. Standardmäßig bindet Ninject nur öffentliche Klassen, Sie müssen 'IncludeNonePublicTypes()' Methode aufrufen, wenn Sie interne Klassen binden wollen. – mivra

2

Sie können es explizit in Ihrem Code aufrufen:

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

Verwenden Sie es 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

Die letzte Bindung wird die vorherigen nicht überschreiben? – Catalin

+0

@MikroDel: Also in Ihrem Beispiel, welche Klasse wird injiziert werden, wenn ein IStartUpTask Interface benötigt wird? Das sieht falsch aus. –

+0

@RaraituL Ich habe meine Antwort aktualisiert, um das Verständnis zu erleichtern – MikroDel

Verwandte Themen