从不同程序集访问静态变量
Accessing a static variable from different assemblies
我有一个 ASP.NET 应用程序和一个 Windows 服务。我使用 Unity 作为 IoC 容器。我将 Composition Root 放在一个单独的 class 库中,因为这两个应用程序应该使用相同的 DI 容器。
DI 引导程序:
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;
}
}
}
DiBootstrapper 上 运行 Initialize() 的第一个项目是 Windows 服务。当method为运行时,设置了_container变量。
之后 ASP.NET 应用程序 运行s Initialize() 来自 Application_Start(),但这次变量为空,容器再次被实例化。
如何在两个项目之间共享同一个容器?
你不能。
这样不行。您有两个不同的进程,Windows 服务和您的网络服务器在调用 ASP.NET 时启动的进程。它们都加载库程序集,但每个都将自己的副本加载到内存中。这就是进程与库一起工作的方式。
没有简单的解决办法。您不能以这种方式共享对象。您将需要找到另一个解决方案。如果您的 DI 容器中没有单例生命周期,那么两个进程具有相同的配置就足够了。如果你想在进程之间共享对象,你可能最好问一个关于如何在特定情况下在特定情况下做到这一点的新问题,因为有很多方法可以在不这样做的情况下实现目标, 但我们需要知道你的目标才能给出这样的答案。
我有一个 ASP.NET 应用程序和一个 Windows 服务。我使用 Unity 作为 IoC 容器。我将 Composition Root 放在一个单独的 class 库中,因为这两个应用程序应该使用相同的 DI 容器。
DI 引导程序:
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;
}
}
}
DiBootstrapper 上 运行 Initialize() 的第一个项目是 Windows 服务。当method为运行时,设置了_container变量。
之后 ASP.NET 应用程序 运行s Initialize() 来自 Application_Start(),但这次变量为空,容器再次被实例化。
如何在两个项目之间共享同一个容器?
你不能。
这样不行。您有两个不同的进程,Windows 服务和您的网络服务器在调用 ASP.NET 时启动的进程。它们都加载库程序集,但每个都将自己的副本加载到内存中。这就是进程与库一起工作的方式。
没有简单的解决办法。您不能以这种方式共享对象。您将需要找到另一个解决方案。如果您的 DI 容器中没有单例生命周期,那么两个进程具有相同的配置就足够了。如果你想在进程之间共享对象,你可能最好问一个关于如何在特定情况下在特定情况下做到这一点的新问题,因为有很多方法可以在不这样做的情况下实现目标, 但我们需要知道你的目标才能给出这样的答案。