0

Ich habe die folgende Klasse in meiner Business-Schicht-Ebene (vereinfachte Code):Unity Kind Container HierarchicalLifetimeManager mvc und Windows-Dienst

public class StatusUpdater : IStatusUpdater 
{ 
    private readonly IStatusRepo _statusRepo; 

    public class StatusUpdater(IStatusRepo statusRepo) 
    { 
     _statusRepo = statusRepo; 
    } 

    public voic UpdateStatus(int id, string newStatus) 
    { 
     _statusRepo.UpdateStatus(id,newStatus); 
    } 
} 

So derzeit in der MVC Seite Ich verwende PerRequestLifetimeManager die Lebensdauer zu steuern der DbContext.

Aber jetzt in der Windows-Dienst kann ich das nicht, so würde ich folgendes tun, aber es fühlt sich nicht richtig, weil es viel wie Servicelocator sieht:

using(var container = ConfiguredContainer.CreateChildContainer()) 
{ 
    var statusUpdater = container.Resolve<IStatusUpdater>(); 
    statusUpdater.UpdateStatus("test"); 
} 

Gibt es noch andere Möglichkeiten? und ist es eine Möglichkeit, den gleichen Code in dem MVC-app und den Windows-Service zu nutzen, ohne dass zwei Arten von Registrierungen:

MVC:

container.RegisterType<IStatusRepo, StatusRepo>(new PerRequestLifetimeManager()); 

Windows:

container.RegisterType<IStatusRepo, StatusRepo>(new HierarchicalLifetimeManager()); 
+0

Nicht sicher über "Unity", aber in anderen DI-Frameworks müssten Sie sowieso einen anderen Registrierungscode für 'MVC' und' Win Service' verwenden. Direkte Aufrufe der 'Resolve'-Methode 'riechen' immer, denn dafür sind DI-Frameworks gedacht - um Instanzen zu lösen, wenn ein Bedarf dafür besteht. Wenn wir die '.Resolve'-Methode in unserem Code aufrufen, bedeutet das höchstwahrscheinlich, dass wir etwas falsch machen. Wir können Instanzen in den Konstruktor einfügen und den Lebensdauerbereich des Objekts ändern, das sie stattdessen verwendet. – Fabjan

Antwort

0

ich in der Regel registrieren meine Typen in ihren eigenen Assemblys, höchstwahrscheinlich wie Sie, aber wenn es etwas gibt, das spezifisch für die ausführende Assembly ist, überschreibe ich es in den Registrierungen dieser ausführenden Assembly.

// In BusinessProcessor 
container.RegisterType<IBusinessProcessorA, MyBusinessProcessorA1>(); 
container.RegisterType<IBusinessProcessorA, MyBusinessProcessorA2>(); 
container.RegisterType<IBusinessProcessorB, MyBusinessProcessorB1>(); 

// In DataAccessLayer 
container.RegisterType<IRepository, Repository<A>>("A", new HierarchicalLifetimeManager()); 
container.RegisterType<IRepository, Repository<B>>("B", new HierarchicalLifetimeManager()); 
container.RegisterType<IRepository, Repository<C>>("C", new HierarchicalLifetimeManager()); 

// In WindowsService 
Register(BusinessProcessor); // Call to have the BusinessProcessor register it's own things. 
Register(DataAccessLayer);  // Call to have the DataAccessLayer register it's own things. 
container.RegisterType<IService, MyService>(); 

// In WebApplication 
Register(BusinessProcessor); // Call to have the BusinessProcessor register it's own things. 
Register(DataAccessLayer);  // Call to have the DataAccessLayer register it's own things. 
container.RegisterType<IController, MyController>(); 
container.RegisterType<IRepository, Repository<A>>("A", new PerRequestLifetimeManager()); 

Eine weitere Möglichkeit Repositories zu registrieren sein könnte, in der DAL, mit unterschiedlichen Namen-Registrierungen, und so für den BusinessProcessors tun, aber das wäre Ihre gesamte Lösung bewusst diese Tatsache bedeuten, die ich nicht empfehlen würde, . Überhaupt.

Verwandte Themen