2016-06-19 6 views
0

Ich habe eine ASP.NET-Anwendung und einen Windows-Dienst. Ich verwende Unity als IoC-Container. Ich habe den Composition Root in eine separate Klassenbibliothek gestellt, da beide Anwendungen den gleichen DI-Container verwenden sollen.Zugriff auf eine statische Variable von verschiedenen Baugruppen

DI Bootstrap:

namespace CompositionRoot { 

public static class DiBootstrapper { 

    private static IUnityContainer _container; 

    public static IUnityContainer Initialize() { 
    return _container ?? (_container = BuildUnityContainer()); 
    } 

    private static IUnityContainer BuildUnityContainer() { 
    var container = new UnityContainer(); 
    container.AddNewExtension<ContainerExtension>(); 
    return container; 
    } 

} 

public class ContainerExtension: UnityContainerExtension { 
    protected override void Initialize() { 
    var connectionString = ConfigurationManager.ConnectionStrings["KSecureEntities"].ConnectionString; 
    var sqlCtorParam = new InjectionConstructor(connectionString); 
    this.Container.RegisterType < Acquaintance.RSS.IRssRepository, RssRepository > (new ContainerControlledLifetimeManager()); 
    this.Container.RegisterType < IRssFeedRepository, RssFeedRepository > (new TransientLifetimeManager(), sqlCtorParam); 
    this.Container.RegisterType<IRssTicker, RssTicker>(new ContainerControlledLifetimeManager()); 
    this.Container.RegisterType <RssTickerHub> (new InjectionFactory(RssTickerHub)); 
    .... 
    } 

    private static object RssTickerHub(IUnityContainer p) { 
    var rssRepository = p.Resolve <IRssFeedRepository>(); 
    var rssTicker = p.Resolve <IRssTicker>(); 
    var rssTickerHub = new RssTickerHub(rssRepository, rssTicker); 
    return rssTickerHub; 
    } 
} 

} 

Das erste Projekt Initialize() auf dem DiBootstrapper ist der Windows-Dienst ausgeführt werden. Wenn die Methode ausgeführt wird, wird die _container-Variable festgelegt.

Anschließend führt die ASP.NET-Anwendung Initialize() aus Application_Start() aus, aber diesmal ist die Variable null und der Container wird erneut instanziiert.

Wie kann ich den gleichen Container für beide Projekte freigeben?

+1

Ein statisches Objekt lebt im Rahmen eines Prozesses. Sie haben zwei: den Service und die Webanwendung. Jeder wird seine eigene Instanz des Containers hosten. Wenn Sie von einem anderen Prozess darauf zugreifen möchten, müssen Sie eine Art von IPC-Protokoll schreiben, das die Aktionen ausführt, die Sie für die Instanz benötigen. Zuerst müssen Sie entscheiden, wo der Container leben soll. Dann müssen Sie einen Dienst implementieren, um dort darauf zuzugreifen. Zuletzt sollten Sie diesen Service aufrufen, um vom Client auf den Container zugreifen zu können. Es gibt viele Möglichkeiten, dies zu tun: .NET Remoting, WCF oder ein High-Level-Framework wie Zyan. – Carsten

Antwort

2

Sie können nicht.

Es funktioniert nicht so. Sie haben zwei verschiedene Prozesse, den Windows-Dienst und den Prozess, den Ihr Webserver beim Aufruf von ASP.NET ausführt. Beide laden die Bibliotheksbaugruppe, aber jeder lädt seine eigene Kopie in den Speicher. So arbeiten Prozesse mit Bibliotheken.

Es gibt keine einfache Lösung. Sie können Objekte auf diese Weise nicht teilen. Sie müssen eine andere Lösung finden. Wenn Sie in Ihrem DI-Container keine Singleton-Lebenszeiten haben, sollte die Konfiguration für beide Prozesse ausreichen. Wenn Sie Objekte zwischen Prozessen teilen möchten, könnten Sie am besten bedient werden, indem Sie eine neue Frage stellen, in einer bestimmten Situation, weil es viele Möglichkeiten gibt, ein Ziel zu erreichen, ohne es zu tun, aber wir müssen Ihr Ziel kennen eine solche Antwort geben.

+0

Danke. Ich habe Singleton Lebenszeiten in meinem Container. Genauer gesagt habe ich einen SignalR-Hub im ASP.NET-Projekt, und ich möchte, dass der Windows-Dienst Hintergrundarbeit leistet und Servernachrichten an die Clients sendet, wenn sie fertig sind. – Kenci