【问题标题】:Accessing a static variable from different assemblies从不同的程序集中访问静态变量
【发布时间】:2016-06-19 18:34:39
【问题描述】:

我有一个 ASP.NET 应用程序和一个 Windows 服务。我使用 Unity 作为 IoC 容器。我将 Composition Root 放在一个单独的类库中,因为这两个应用程序都应该使用相同的 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 服务。运行该方法时,会设置 _container 变量。

之后,ASP.NET 应用程序从 Application_Start() 运行 Initialize(),但这次变量为空,并且容器再次被实例化。

如何在两个项目之间共享同一个容器?

【问题讨论】:

  • 静态对象存在于进程的范围内。您有两个:服务和 Web 应用程序。每个都将托管它自己的容器实例。如果您想从不同的进程访问它,您必须编写某种 IPC 协议来在实例上执行您需要的操作。首先你必须决定容器应该放在哪里。然后你必须实现一个服务来访问它。最后,您应该调用此服务以便从客户端访问容器。有很多方法可以做到这一点:.NET Remoting、WCF 或 Zyan 等高级框架。

标签: c# unity-container


【解决方案1】:

你不能。

这种方式是行不通的。您有两个不同的进程,Windows 服务和您的网络服务器在调用 ASP.NET 时启动的进程。他们都加载库程序集,但每个人都将自己的副本加载到内存中。这就是流程与库一起工作的方式。

没有简单的解决方案。您不能以这种方式共享对象。您将需要找到另一种解决方案。如果您的 DI 容器中没有单例生命周期,那么只需对两个进程进行相同的配置就足够了。如果您想在进程之间共享对象,最好提出一个关于如何在特定情况下执行此操作的新问题,因为有很多方法可以在不这样做的情况下实现目标,但我们需要知道你的目标才能给出这样的答案。

【讨论】:

  • 谢谢。我的容器中有单身人士的生命周期。更准确地说,我在 ASP.NET 项目中有一个 SignalR 集线器,我希望 Windows 服务完成后台工作并向客户端广播服务器消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 2012-06-29
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多