我有一个ASP.NET应用程序和一个Windows服务。我使用Unity作为IoC容器。我将Composition Root放在一个单独的类库中,因为两个应用程序都应该使用相同的DI容器。
DI bootstrapper:
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(),但这次变量为null,并且容器再次被实例化。
如何在两个项目中共享同一个容器?</ p>
答案 0 :(得分:2)
它不起作用。您有两个不同的进程,Windows服务和您的Web服务器在调用ASP.NET时进行调整的过程。它们都加载库程序集,但每个都将自己的副本加载到内存中。这就是流程如何与图书馆合作。
没有简单的解决方案。你不能这样分享对象。您需要找到另一种解决方案。如果您的DI容器中没有单例生命周期,那么只需为两个进程配置相同的配置即可。如果你想在进程之间共享对象,最好通过询问一个关于如何在特定情况下执行该操作的新问题,因为有很多方法可以实现目标而不用它,但我们需要知道你的目标才能得到这样的答案。