2014-12-19 4 views
2

Я пытаюсь уничтожить все свои службы бизнес-логики после каждого вызова WCF и попытаться добиться его с помощью windsor (Ninject просто не работает), у меня есть следующий контейнерный класс:Замок Виндзор повторно создайте экземпляр

public class LDSWindsorContainer : WindsorContainer 
    { 
     public LDSWindsorContainer() 
     { 
      AddFacility<WcfFacility>(). 
       Register(
        Component.For<IDomainService>().ImplementedBy<DomainService>().LifeStyle.PerWcfOperation(), 
        Component.For<IChangeLogService>().ImplementedBy<ChangeLogService>().LifeStyle.PerWcfOperation(), 
        Component.For<ILogService>().ImplementedBy<LogService>().LifeStyle.PerWcfOperation(), 
        Component.For<ICentreInformationService>() 
         .ImplementedBy<CentreInformationService>() 
         .LifeStyle.PerWcfOperation().OnCreate(x=>Debug.WriteLine("Created")), 
        Component.For<ICentreService>().ImplementedBy<CentreService>().LifeStyle.PerWcfOperation(), 
        Component.For<ITimeZoneService>().ImplementedBy<TimeZoneService>().LifeStyle.PerWcfOperation(), 
        Component.For<IBrandService>().ImplementedBy<BrandService>().LifeStyle.PerWcfOperation(), 
        Component.For<IPricingService>().ImplementedBy<PricingService>().LifeStyle.PerWcfOperation(), 
        Component.For<IDirectoryService>() 
         .ImplementedBy<DirectoryService>().LifestyleSingleton()); 
     } 
    } 

всех объектов, кроме IDirectoryService и его реализаций моей бизнес-логика услуги, последний из которых является сам WCF сервис, у меня есть метод следующего Application_Start():

  public class Global : System.Web.HttpApplication 
     { 

      protected void Application_Start(object sender, EventArgs e) 
      { 
       var container = new LDSWindsorContainer(); 
       ... 
      } 
     } 

и конструктор моего сервиса выглядит так:

  private ILogService Logger { get; set; } 
      private IDomainService DomainService { get; set; } 
      private ICentreInformationService CentreInformationService { get; set; } 
      private ICentreService CentreService { get; set; } 
      private ITimeZoneService TimeZoneService { get; set; } 
      private IBrandService BrandService { get; set; } 
      private IPricingService PricingService { get; set; } 

      public DirectoryService(IBrandService brandService, ITimeZoneService timeZoneService, ICentreService centreService, ICentreInformationService centreInformationService, IDomainService domainService, ILogService logger, IPricingService pricingService) 
      { 
       BrandService = brandService; 
       TimeZoneService = timeZoneService; 
       CentreService = centreService; 
       CentreInformationService = centreInformationService; 
       DomainService = domainService; 
       Logger = logger; 
       PricingService = pricingService; 
      } 

У меня также есть соответствующая строка в моей DirectoryService.svc и Web.config -

Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration  

и

<system.webServer> 
     <modules runAllManagedModulesForAllRequests="true" > 
      <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" /> 
     </modules> 
</system.webServer> 

До сих пор проблема: мои экземпляры становятся решены разы (для первого вызова), работайте нормально, выходите на конец вызова и не повторно создаете для всех предстоящих вызовов, так что в основном я просто получаю исключение для работы с расположенным объектом, любые идеи очень ценятся, ank вы заранее.

+2

Вашей службы каталогов настроена как синглтон, но зависимости, которые вводят в конфигурируются для каждого запроса, так что это было бы нормальное поведение, я думаю. Вы должны либо сделать свой образ жизни службы каталогов за веб-запрос, либо сделать свои другие сервисы одиночными. –

+0

К сожалению, в этом конкретном случае я не могу изменить поведение службы, но вам нужно воспользоваться преимуществами запроса DI, поэтому я все еще ищу вариант здесь – HardLuck

+0

Когда вы говорите, что не можете изменить поведение, вы имеете в виду вы не можете изменить образ жизни услуг? Кроме того, служба каталогов должна быть одиночной? –

ответ

0

ИТАК после некоторой борьбы я был в состоянии найти идеальный ответ здесь -

Мои настройки контейнера:

 AddFacility<TypedFactoryFacility>().Register(Component.For<IDomainService>().ImplementedBy<DomainService().LifeStyle.PerWcfOperation(), 

    AddFacility<WcfFacility>().Register(Component.For<IDirectoryService>().ImplementedBy<DirectoryService>().LifestyleSingleton()); 

Где IDomainService это мое обслуживание бизнес-логики, что я хочу, чтобы избавиться после каждого запроса и IDirectoryService - это моя служба WCF.

Моей служба sontructor

public DirectoryService(Func<IDomainService> domainService) 
    { 
     DomainServiceFactory = domainService; 
    } 

и немного сахара, чтобы избежать всех вызовов переименования:

private Func<IDomainService> DomainServiceFactory { get; set; } 

    private IDomainService DomainService 
    { 
     get { return DomainServiceFactory(); } 
    } 
+0

Предположительно у вас есть один из них для каждой зависимости? Интересное решение, но, похоже, вы внедряете знания/предположения о жизненном цикле IDomainService в DirectoryService.IoC/DI обычно относится к развязывающим зависимостям, тогда как это решение, допускающее замену типа, оставляет вещи очень плотно связанными. Например, если жизненный цикл одной из ваших зависимостей изменен с PerWcfOperation на Transient, то ваш сервис, скорее всего, не удастся. –

+0

Ну, все это не изменится на переходный процесс, потому что он предназначен для размещения сервисов после каждого запроса, поэтому мои вызовы контекста db не будут кэшироваться. – HardLuck

+0

Вы имеете дело с тем, что Mark Seemann называет проблемой Captive Dependency: http://blog.ploeh.dk/2014/06/02/captive-dependency/ Да, ваше решение будет работать, но чрезвычайно хрупкое и заставляет меня задаться вопросом какое значение вы добавляете с помощью DI. Похоже, что то, что здесь происходит, очень запутанно для тех, кто поддерживает этот код позже. –

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