2012-04-11 7 views
5

Wir haben eine Lösung mit mehreren Projekten, die die Schichten unserer Anwendung darstellen. z.B.Ist es möglich, Castle Windsor Eigentumsabhängigkeiten zu lösen, wenn Sie keinen Bezug auf den Container haben?

Domain

Daten

Logic

WebUI

Unser Schloss Windsor Behälter wird von unserer Web-Schicht bezeichnet und wir diese Abhängigkeiten dann nach oben durch unsere Schichten kaskadieren. Zum Beispiel ...

// In Domain 
public interface IFooRepository 
{ 
    void DoSomething(); 
} 

// In Data 
public class FooRepository : IFooRepository 
{ 
    public void DoSomething() 
    { 
     // Something is done 
    } 
} 

// In Logic 
public class MyThingManager 
{ 
    private readonly IFooRepository fooRepository; 

    public MyThingManager(IFooRepository fooRepository) 
    { 
     this.fooRepository = fooRepository; 
    } 

    public void AMethod() 
    { 
     this.fooRepository.DoSomething(); 
    } 

} 

// In Web 
// in some controller.... 
var newManager = new MyThingManager(WindsorContainer.Resolve<IFooRepository>()); 
newManager.DoSomething(); 

und das funktioniert gut, bis unsere Manager viele Mitglieder haben, die ihre eigenen Abhängigkeiten haben. Wenn dies geschieht, lösen wir die Dependenzen des Managers und deren Dependenzen und kaskadieren sie von der Webschicht. Das Ergebnis sind einige ziemlich große Konstruktoren.

Gibt es einen eleganteren Weg, zum Beispiel, dass die inneren Komponenten eines Managers seine eigenen Abhängigkeiten auflösen, ohne Zugriff auf den Container zu haben?

Bedenken Sie, dass NUR die Web-Schicht Zugriff auf den Container hat (um eine zirkuläre Projektabhängigkeit zu verhindern), so kann nur die Web-Layer WindsorContainer.Resolve() die logische Ebene nicht so die einzige Möglichkeit zu kaskadieren Eine Abhängigkeit ohne die Container-Unterstützung bestand darin, sie in der Web-Ebene aufzulösen und dann die Kette über ihre Schnittstelle weiterzuleiten.

+2

"Wir enden damit, sowohl die Managerabhängigkeiten als auch ihre Abhängigkeitsdepandanzen aufzulösen und sie von der Webschicht zu kaskadieren." Ich verstehe das nicht. Wenn Sie die Konstruktorinjektion verwenden und der Container die Abhängigkeiten automatisch in den Konstruktor eines Typs eingibt, sollte dies keinerlei Probleme verursachen. Ein bisschen mehr Code, der dieses Problem visualisiert, könnte hilfreich sein. – Steven

Antwort

6

Kurze Antwort ist, dass, wenn Sie .Resolve<T> sehen, Sie wahrscheinlich doing it wrong sind. Wie @steven bereits erwähnt hat, möchten Sie die eingebauten Funktionen von Windsor nutzen, um Ihnen die Konstruktorinjektion (und/oder die Eigenschafteninjektion) zur Verfügung zu stellen. Das bedeutet, dass WindsorContainer das Objekt kennen muss, das sich im Stammverzeichnis Ihres Objektdiagramms befindet.

In Ihrem Fall würden Sie den Baum der Objekte hinaufgehen (von MyThingyManager), bis Sie zum Stammobjekt gelangen. In einer ASP.NET MVC-Anwendung wäre dies beispielsweise der Controller, der die aufgerufene Aktion enthält. Für den MVC3-Fall würden Sie eine DependencyResolver verwenden, um die Injektion aller Abhängigkeiten zu starten.

Weiter, was ich in Windsor in der Vergangenheit nützlich gefunden habe, ist ein anderer Installer pro Komponente (Assembly). Anschließend registrieren Sie diese Installationsprogramme an der Basis des Prozesses, der die Anwendung hostet.

So in jeder Komponente würden Sie ein Installationsprogramm wie haben:

var container = new WindsorContainer(); 
container.Install(FromAssembly.This()); 
container.Install(FromAssembly.Containing(typeof(ComponentThatContains.MyThingManager.Installer))); 

Dies gibt Ihnen einen Weg:

public class Installer : IWindsorInstaller 
{ 
     public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store) 
     { 
      container.Register(
       Component.For<IMyThingManager>().ImplementedBy<MyThingManager>(), 
       Component.For<IFooRepository>().ImplementedBy<FooRepository>() 
       ); 
     } 
} 

Und dann in der Global.asax.cs Application_Start Sie so etwas wie hätte um alle Abhängigkeiten im gesamten Objektgraphen zu verwalten und durch Konstruktorinjektion aufzulösen. Hoffe, das hilft.

+0

Danke dafür, es begann ein komplett neues überdenken, wie wir IOC tun und es funktioniert jetzt wie Magie: D –

+0

Schön zu hören, froh, dass ich helfen konnte. –