2016-04-27 12 views
0

現在、次のような例外が発生していますが、発生するタイミングを特定できませんでした。私の賭けはおそらくそれがUnityの依存性注入コンテナとタイプの登録方法に関係しているということです。ここではエラーがあります:Unityと統合されたSignalRのPerRequestLifetimeManagerに関連する例外

The PerRequestLifetimeManager can only be used in the context of an HTTP request. Possible causes for this error are using the lifetime manager on a non-ASP.NET application, or using it in a thread that is not associated with the appropriate synchronization context. 

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: The PerRequestLifetimeManager can only be used in the context of an HTTP request. Possible causes for this error are using the lifetime manager on a non-ASP.NET application, or using it in a thread that is not associated with the appropriate synchronization context. 

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Stack Trace: 


[InvalidOperationException: The PerRequestLifetimeManager can only be used in the context of an HTTP request. Possible causes for this error are using the lifetime manager on a non-ASP.NET application, or using it in a thread that is not associated with the appropriate synchronization context.] 
    Microsoft.Practices.Unity.Mvc.UnityPerRequestHttpModule.GetDictionary(HttpContext context) +195 
    Microsoft.Practices.Unity.Mvc.UnityPerRequestHttpModule.GetValue(Object lifetimeManagerKey) +50 
    Microsoft.Practices.ObjectBuilder2.LifetimeStrategy.PreBuildUp(IBuilderContext context) +146 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +396 
    Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +130 
    lambda_method(Closure , IBuilderContext) +206 
    Microsoft.Practices.ObjectBuilder2.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context) +33 
    Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +337 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +396 
    Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +130 
    lambda_method(Closure , IBuilderContext) +206 
    Microsoft.Practices.ObjectBuilder2.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context) +33 
    Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +337 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +396 
    Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +130 
    lambda_method(Closure , IBuilderContext) +212 
    Microsoft.Practices.ObjectBuilder2.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context) +33 
    Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +337 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +396 
    Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) +238 

[ResolutionFailedException: Resolution of the dependency failed, type = "TradeForce.Portal.Hubs.ExecutionReportsHub", name = "(none)". 
Exception occurred while: while resolving. 
Exception is: InvalidOperationException - The PerRequestLifetimeManager can only be used in the context of an HTTP request. Possible causes for this error are using the lifetime manager on a non-ASP.NET application, or using it in a thread that is not associated with the appropriate synchronization context. 
----------------------------------------------- 
At the time of the exception, the container was: 

    Resolving TradeForce.Portal.Hubs.ExecutionReportsHub,(none) 
    Resolving parameter "iExecutionReportsBusiness" of constructor TradeForce.Portal.Hubs.ExecutionReportsHub(TradeForce.Dominio.Interfaces.Business.Reports.IExecutionReportsBusiness iExecutionReportsBusiness, TradeForce.Dominio.Interfaces.Repository.NH.IUsers iUsers, TradeForce.Dominio.Interfaces.Repository.NH.ICollaborators iCollaborators, TradeForce.Infraestrutura.Persistencia.NHibernateUtil.SessionProvider sessionProvider) 
    Resolving TradeForce.Business.Entities.Reports.ExecutionReportsBusiness,(none) (mapped from TradeForce.Dominio.Interfaces.Business.Reports.IExecutionReportsBusiness, (none)) 
    Resolving parameter "iExecutionReports" of constructor TradeForce.Business.Entities.Reports.ExecutionReportsBusiness(TradeForce.Dominio.Interfaces.Repository.NH.Reports.IExecutionReports iExecutionReports) 
     Resolving TradeForce.Infraestrutura.DAO.NH.Reports.DAOExecutionReports,(none) (mapped from TradeForce.Dominio.Interfaces.Repository.NH.Reports.IExecutionReports, (none)) 
     Resolving parameter "sessionProvider" of constructor TradeForce.Infraestrutura.DAO.NH.Reports.DAOExecutionReports(TradeForce.Infraestrutura.Persistencia.NHibernateUtil.SessionProvider sessionProvider) 
     Resolving TradeForce.Infraestrutura.Persistencia.NHibernateUtil.SessionProvider,(none) 
] 
    Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) +500 
    Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) +20 
    TradeForce.Portal.Helpers.UnityHubActivator.Create(HubDescriptor descriptor) +108 
    Microsoft.AspNet.SignalR.Hubs.HubDispatcher.CreateHub(IRequest request, HubDescriptor descriptor, String connectionId, StateChangeTracker tracker, Boolean throwIfFailedToCreate) +601 
    Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReceived(IRequest request, String connectionId, String data) +614 
    Microsoft.AspNet.SignalR.<>c__DisplayClassc.<ProcessRequestPostGroupRead>b__7() +41 
    Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod(Func`1 func) +25 
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +181 
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +69 
    Microsoft.AspNet.SignalR.Transports.<ProcessSendRequest>d__12.MoveNext() +944 
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +181 
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +69 
    Microsoft.Owin.Mapping.<Invoke>d__0.MoveNext() +599 
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +181 
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +69 
    Microsoft.Owin.Mapping.<Invoke>d__0.MoveNext() +870 
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +181 
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +69 
    Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.<RunApp>d__5.MoveNext() +203 
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +181 
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +69 
    Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.<DoFinalWork>d__2.MoveNext() +193 
    Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) +96 
    System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +509 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +146 

はここでユニティを利用しているSignalRのハブです:

public class ExecutionReportsHub : BaseHub 
{ 
    private readonly IExecutionReportsBusiness _iExecutionReportsBusiness; 
    private readonly IUsers _iUsers; 
    private readonly ICollaborators _iCollaborators; 
    private readonly SessionProvider _sessionProvider; 

    public ExecutionReportsHub(IExecutionReportsBusiness iExecutionReportsBusiness, IUsers iUsers, ICollaborators iCollaborators, SessionProvider sessionProvider) 
    { 
     _iExecutionReportsBusiness = iExecutionReportsBusiness; 
     _iUsers = iUsers; 
     _iCollaborators = iCollaborators; 
     _sessionProvider = sessionProvider; 
    } 

    // More code... 
} 

タイプ登録:

public class UnityConfig 
{ 
    public static void RegisterTypes(IUnityContainer container) 
    { 
     container.RegisterInstance(new SessionFactoryProvider()); 
     container.RegisterType<SessionProvider>(new PerRequestLifetimeManager()); 

     container.RegisterType<IUsers, DAOUsers>(); 
     container.RegisterType<ICollaborators, DAOCollaborators>(); 
     container.RegisterType<IExecutionReportsBusiness, ExecutionReportsBusiness>(); 

     container.RegisterType<IHubActivator, UnityHubActivator>(new PerRequestLifetimeManager()); 
     container.RegisterType<ExecutionReportsHub, ExecutionReportsHub>(new ContainerControlledLifetimeManager()); 

     // Other unrelated types being registered... 
    } 
} 

エラーは以下のいずれかの実行中に発生していますハブ・メソッドはクライアント側コールから取得します。

ありがとうございます。

+0

public class HubActivator : IHubActivator { private readonly IUnityContainer _container; private readonly IHubContainer<ExecutionReportsHub> _hubContainer; public HubActivator(IUnityContainer container) { _container = container; _hubContainer = container.Resolve<IHubContainer<ExecutionReportsHub>>(); } public IHub Create(HubDescriptor descriptor) { object hub = _container.Resolve(descriptor.HubType) ?? Activator.CreateInstance(descriptor.HubType); if (hub is ExecutionReportsHub) { _hubContainer.Add(hub as ExecutionReportsHub); } return hub as IHub; } } public class ExecutionReportsHubContainer : IHubContainer<ExecutionReportsHub> { public ExecutionReportsHubContainer() { _hubs = new List<ExecutionReportsHub>(); } private IList<ExecutionReportsHub> _hubs { get; set; } public void Add(ExecutionReportsHub hub) { _hubs.Add(hub); } public void Remove(ExecutionReportsHub hub) { _hubs.Remove(hub); } public void Dispose(string connectionId) { IEnumerable<ExecutionReportsHub> hubs = _hubs.Where(x => x.ConnectionId.Equals(connectionId)).ToList(); foreach (var hub in hubs) { hub.Detach(); Remove(hub); hub.Dispose(); } } } public interface IHubContainer<T> where T : IHub { void Dispose(string connectionId); void Remove(IFlowHub flowHub); void Add(IFlowHub flowHub); } 

そして、あなたの登録。 [SignalR内部であるため、要求ごとのライフタイム依存性についてはSignalRにはサポートがありません。](http://docs.autofac.org/en/latest/integration/signalr.html) –

+0

ありがとう@ErkanDemirel私は見ていきますそれがうまくいくかどうかをここに報告してください。 – Zignd

答えて

0

私はあなたにお勧めしますではないは、ハブの寿命を制御します。これはパイプラインによって管理されます。

APIガイドから:http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-server#hubclass

You don't instantiate the Hub class or call its methods from your own code on the server; all that is done for you by the SignalR Hubs pipeline. SignalR creates a new instance of your Hub class each time it needs to handle a Hub operation such as when a client connects, disconnects, or makes a method call to the server.

Because instances of the Hub class are transient, you can't use them to maintain state from one method call to the next. Each time the server receives a method call from a client, a new instance of your Hub class processes the message. To maintain state through multiple connections and method calls, use some other method such as a database, or a static variable on the Hub class, or a different class that does not derive from Hub. If you persist data in memory, using a method such as a static variable on the Hub class, the data will be lost when the app domain recycles.

あなたはまだLifeTimeManagerを持つことができ、HubActivatorとユニティを使用することができます。しかし、ハブの寿命を管理しようとすると、しばらくすると予期せぬ動作に陥るでしょう。

そして、PerRequestLifeTimeManagerを使用すると、SignalRとハブの機能がそのまま使用できません。部分的にはHttpContextのためです。これはUnityPerRequestHttpModuleを使用しており、順にHttpContext.Currentを使用しています。

internal static void SetValue(object lifetimeManagerKey, object value) 
{ 
    Dictionary<object, object> dictionary = UnityPerRequestHttpModule.GetDictionary(HttpContext.Current); 
    if (dictionary == null) 
    { 
    dictionary = new Dictionary<object, object>(); 
    HttpContext.Current.Items[UnityPerRequestHttpModule.ModuleKey] = (object) dictionary; 
    } 
    dictionary[lifetimeManagerKey] = value; 
} 

およびHttpContext.Currentは常にハブではnullです。 Context.Request.GetHttpContext()を使用して独自の実装を作成することができます。

ただし、実際にハブのライフタイムを管理する必要がある場合は、HubContainerを作成することができます。私はハブを制御する必要があるときにこれを1つのプロジェクトで行いました。あなたがハブにリクエストごとに持つべきではない

unityContainer.RegisterType<IHubContainer<ExecutionReportsHub>, ExecutionReportsHubContainer >(new ContainerControlledLifetimeManager()); 
unityContainer.RegisterType<IHubActivator, HubActivator>(new ContainerControlledLifetimeManager()) 
関連する問題