Laden...

DI-Container, LightCore: Instanz von algemeinerem Interface automatisch Resolven

Erstellt von Uwe81 vor 11 Jahren Letzter Beitrag vor 11 Jahren 710 Views
U
Uwe81 Themenstarter:in
282 Beiträge seit 2008
vor 11 Jahren
DI-Container, LightCore: Instanz von algemeinerem Interface automatisch Resolven

Hallo, der Titel ist etwas blöd, aber in Code ist es leicht zu erklären, was ich suche...


using LightCore;

interface IFoo {
    void DoFoo();
}

interface IBar : IFoo {
    void DoBar();
}

class Bar : IBar {
    public void DoFoo() {}
    public void DoBar() {}
}

class Program {
    public static void Main() {
        var builder = new ContainerBuilder();
        builder.Register<IBar, Bar>();
        var container = builder.Build();
        var foo = container.Resolve<IFoo>();
    }
}

Bei der letzten Zeile fliegt eine Exception. Ist auch klar, weil kein IFoo registriert ist. Allerdings kennt der Container ja ein IBar und weiß, dass das auch ein IFoo ist. Gibt es eine Möglichkeit, dass das automatisch aufgelöst wird?

Was geht (mir aber nicht so gut gefällt) ist


builder.Register<IBar, Bar>();
builder.Register<IFoo, Bar>();

oder


builder.Register<IBar, Bar>();
builder.Register<IFoo>(c => c.Resolve<IBar>());

Mir ist das ganze deshalb wichtig, weil ich ein Framwork entwickel, welches dann von anderen verwendet wird. Innerhalb des Framworks will ich (aus Kapeselungsgründen) möglichst spezialisierte Interfaces durch die Gegend reichen, nach außen will ich aber für den Benutzer meines Frameworks die Konfiguration des DI Containers möglichst einfach halten.

Viele Grüße und vielen Dank,
Uwe

106 Beiträge seit 2011
vor 11 Jahren

Hallo Uwe81,

Was geht (mir aber nicht so gut gefällt) ist

  
builder.Register<IBar, Bar>();  
 builder.Register<IFoo, Bar>();   
  

oder

  
builder.Register<IBar, Bar>();  
builder.Register<IFoo>(c => c.Resolve<IBar>());   
  

Ist aber aus meiner Sicht die beste Lösung. Stell dir vor, du würdest deinem Container beibringen, alle Interfaces aus den Klassen auszulesen, die du registriest und die dann auch noch registrierst. Dann könntest du ausversehen eine vorherige Registrierung überschrieben, oder du registrierst eine weitere Klasse die IFoo implementiert, dann weiß dein Container auch nicht mehr ob er Bar oder die andere klasse zurück geben soll.

Mach es am besten so, wie du es oben vorgeschlagen hast.

MfG
Rabban

5.941 Beiträge seit 2005
vor 11 Jahren

Hallo Uwe

Premature optimization is the root of all evil 😃

Das würde schon irgendwie gehen, du könntest die Registrierungen durchgehen und das automatisieren indem du ein RegistrationModule schreibst.

Aber ich würde davon abraten wie Rabban, weil das doch schnell Konflikte geben kann, die du auch nicht soo einfach individuell ändern kannst, wenn du es automatisierst.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

U
Uwe81 Themenstarter:in
282 Beiträge seit 2008
vor 11 Jahren

Stimmt, im allgemeinen führt das vermutlich zu Problemen.

Da ich die Kombination von IFoo und IBar ja im voraus kenne, habe ich nun einfach ExtensionsMethods geschrieben.


static void RegisterBar<TBar>() where TBar:IBar {
    builder.Register<IBar, Bar>();
    builder.Register<IFoo, Bar>();
}

Irgendwie habe ich erst versucht, das über ein RegistrationModule zu machen, aber da das später immer im Code konfiguriert wird, kann ich es eigentlich auch direkt per EtensionMethod machen (dennoch ist es interessant, RegistrationModules zu kennen).

Vielen Dank für den Fingerzeig in die richtige Richtung,
Uwe