【发布时间】: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