2015-01-22 5 views
1

우리는성 윈저에서 스코프 캐시가 이미 버려졌습니다. SignalR 허브에

  • .NET 4.5.1
  • MVC 5.2.2
  • OWIN
  • WebApi 2.2
  • SignalR 2.2.0
  • 기반으로하는 웹 응용 프로그램을 개발하는 성 Windsor 3.3.0
  • Wcf 통합 시설 3.3.0
우리가 해결되지 않는

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(); 
    } 
} 

유의 사항 : 우리가 WindsorDependencyResolver 클래스를 사용 종속성을 해결하기위한 http://docs.castleproject.org/Windsor.Windsor-tutorial-part-two-plugging-Windsor-in.ashx

: 컨트롤러를 해결하기위한

우리는 아래 페이지에 설명 된 ControllerFactory 클래스를 사용 Windsor 컨테이너가있는 SignalR의 IHub 클래스는 파이프 라인에서 OWIN 시스템으로 인스턴스화됩니다. Startup.cs 코드는 다음과 같습니다 :

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

컨트롤러, WCF 서비스 클라이언트 및 로깅 클래스 -를 -excepting 인터셉터의 모든

프로젝트에 LifestylePerWebRequest에 등록됩니다. 그러나 우리가 로깅을 위해 사용하는 클래스는 싱글 톤입니다. 그래서

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

우리는 아래의 예외를 얻을 SignalR 허브에 웹 요청 lifestyle- 당이 - 어떤은 WCF 클라이언트를 해결하려고 : 아래의 Web.config의 설정이 있습니다

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 

Container.Resolve() 메서드를 호출하기 전에 디버거 창에서 HttpContext를 볼 수 있습니다. 그건 그렇고, 싱글 톤 로깅 클래스를 해결할 수 있습니다.

흥미로운 점은 팀원은 예외가되지 않는다는 것입니다. 가장 큰 차이점은 OS 버전입니다. 나는 윈도우 8.1에서 코드를 실행하고 팀원은 윈도우 7에서 그것을 실행한다.

오직 signalr 허브에 대해서만이 예외가 발생한다. 다른 어떤 곳에서도 예외가 없습니다. 이 문제를 어떻게 해결할 수 있습니까?

답변

0

Startup 클래스의 IDependencyResolver를 해결하기 위해 ServiceLocator를 사용합니다. 모양은 다음과 같습니다.

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); 
    } 
} 

어쩌면 도움이 될지도 모릅니다.