2015-01-22 6 views
1

Мы разрабатываем веб-приложения на основеКэш «Виндзорский замок» уже был установлен ». в SignalR концентраторы

  • .NET 4.5.1
  • MVC 5.2.2
  • Owin
  • WebAPI 2,2
  • SignalR 2.2.0
  • Castle.Windsor 3.3.0
  • Wcf Integration Facility 3.3.0

Для решения контролеров мы используем ControllerFactory класс, который был описан на странице ниже: http://docs.castleproject.org/Windsor.Windsor-tutorial-part-two-plugging-Windsor-in.ashx

Для разрешения зависимостей мы используем WindsorDependencyResolver класс:

public class WindsorDependencyResolver : IDependencyResolver 
{ 
    public IWindsorContainer Container { get; private set; } 

    public WindsorDependencyResolver(IWindsorContainer windsorContainer) 
    { 
     Container = windsorContainer; 
    } 

    public IDependencyScope BeginScope() 
    { 
     return new WindsorDependencyScope(this.Container); 
    } 

    public object GetService(Type serviceType) 
    { 
     return this.Container.Kernel.HasComponent(serviceType) ? this.Container.Resolve(serviceType) : null; 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     return this.Container.ResolveAll(serviceType).Cast<object>().ToArray(); 
    } 

    public void Dispose() 
    { 
    } 
} 

public class WindsorDependencyScope : IDependencyScope 
{ 
    public IWindsorContainer Container { get; set; } 
    public IDisposable Scope { get; set; } 

    public WindsorDependencyScope(IWindsorContainer container) 
    { 
     this.Container = container; 
     this.Scope = container.BeginScope(); 
    } 

    public object GetService(Type serviceType) 
    { 
     return this.Container.Kernel.HasComponent(serviceType) ? this.Container.Resolve(serviceType) : null; 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     return this.Container.ResolveAll(serviceType).Cast<object>().ToArray(); 
    } 

    public void Dispose() 
    { 
     this.Scope.Dispose(); 
    } 
} 

Имейте в виду, что мы не разрешить Классы IHub SignalR с контейнером Windsor, они создаются системой OWIN в конвейере. Код Startup.cs показан ниже:

public partial class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     ConfigureAuth(app); 
     app.MapSignalR(); 
    } 
} 

Все контроллеры, ФОС обслуживания клиентов и перехватчиков -excepting протоколирования классами: зарегистрированы LifestylePerWebRequest в проекте. Однако классы, которые мы используем для ведения журнала, являются одиночными.

Существует параметр в поле ниже Web.config:

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

Так что, когда мы пытаемся разрешить клиенту ФОС -Какой есть на веб-запроса в жизни, до- ступице SignalR мы получаем ниже исключение:

System.ObjectDisposedException: Cannot access a disposed object. 
Object name: 'Scope cache was already disposed. This is most likely a bug in the calling code.'. 
    at Castle.MicroKernel.Lifestyle.Scoped.ScopeCache.get_Item(Object id) 
    at Castle.MicroKernel.Lifestyle.Scoped.DefaultLifetimeScope.GetCachedInstance(ComponentModel model, ScopedInstanceActivationCallback createInstance) 
    at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) 
    at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) 
    at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) 
    at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context) 
    at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy) 
    at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) 
    at Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments) 
    at Castle.Windsor.WindsorContainer.Resolve[T]() 
    at UIServer.WebUI.Hubs.MailThreadHub.Broadcast(MailMessageListDto mailMessage) in c:\Development\DDD\UIServer.WebUI\Hubs\MailThreadHub.cs:line 92 

Я вижу HttpContext в окне отладчика перед вызовом метода Container.Resolve(). Между прочим, я могу разрешить классы журнала singleton.

Интересным моментом является то, что мой товарищ по команде не получает никаких исключений. Основное отличие - наши версии ОС. Я запускаю код в Windows 8.1, а мой партнер по команде запускает его в окнах 7.

Мы получаем это исключение только для концентраторов signalr. Мы не получаем никаких исключений ни в одном другом месте. Как мы можем решить эту проблему?

ответ

0

Я использую ServiceLocator для разрешения IDependencyResolver в классе Startup. Это выглядит так:

internal class Startup 
{ 
    public void Configuration(IAppBuilder appBuilder) 
    { 
     var config = new HttpConfiguration(); 
     config.Routes.MapHttpRoute("ActionApi", "{controller}/{action}/{id}", new {id = RouteParameter.Optional}); 

     config.DependencyResolver = ServiceLocator.Instance.Resolve<IDependencyResolver>(); 

     appBuilder.UseWebApi(config); 
    } 
} 

Возможно, это помощь.