2016-06-19 7 views
0

У меня есть приложение ASP.NET и служба Windows. Я использую Unity в качестве контейнера IoC. Я поместил Root Composition в отдельную библиотеку классов, потому что оба приложения должны использовать один и тот же контейнер 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; 
    } 
} 

} 

Первый проект для запуска Initialize() на DiBootstrapper является службы Windows. Когда этот метод запущен, устанавливается переменная _container.

После этого приложение ASP.NET запускает Initialize() из Application_Start(), но на этот раз переменная имеет значение null, и контейнер снова создается экземпляр.

Как я могу использовать один и тот же контейнер для обоих проектов?

+1

Статический объект живет в рамках процесса. У вас есть два: служба и веб-приложение. Каждый из них будет размещать собственный экземпляр контейнера. Если вы хотите получить к нему доступ из другого процесса, вам нужно написать какой-то IPC-протокол, который выполняет действия, необходимые для экземпляра. Сначала вы должны решить, где должен жить контейнер. Затем вам нужно реализовать службу для доступа к ней. Последнее вы должны позвонить этой службе, чтобы получить доступ к контейнеру от клиента. Есть много способов сделать это: .NET Remoting, WCF или некоторые высокоуровневые структуры, такие как Zyan. – Carsten

ответ

2

Вы не можете.

Это не работает. У вас есть два разных процесса: служба Windows и процесс, который ваш веб-сервер закручивает, когда вы вызываете ASP.NET. Они загружают сборку библиотеки, но каждый загружает свою собственную копию в память. Вот как работают процессы с библиотеками.

Это не простое решение. Вы не можете обмениваться объектами таким образом. Вам нужно будет найти другое решение. Если в вашем контейнере DI нет жизненных циклов одноэлементного режима, достаточно иметь такую ​​же конфигурацию для обоих процессов. если вы хотите обмениваться объектами между процессами, вам может быть лучше всего задавать новый вопрос о том, как это сделать в конкретной ситуации, потому что есть много способов достичь цели, не делая этого, но нам нужно знать вашу цель дать такой ответ.

+0

Спасибо. В моем контейнере есть однолетние жизни. Точнее, у меня есть компонент SignalR в проекте ASP.NET, и я хочу, чтобы служба Windows выполняла фоновые работы и передавала сообщения сервера клиентам, когда они заканчиваются. – Kenci

Смежные вопросы