2
votes

I try to implement the here proposed integration. Unfortunately my hub methods are not called. This exception preventing it:

SimpleInjector.ActivationException occured. HResult=-2146233088
Message=The disposed object cannot be accessed. Objektname: "SimpleInjector.Scope". Source=SimpleInjector StackTrace: bei SimpleInjector.InstanceProducer.GetInstance() InnerException: HResult=-2146232798 Message=The disposed object cannot be accessed. Objektname: "SimpleInjector.Scope". ObjectName=SimpleInjector.Scope Source=SimpleInjector StackTrace: bei SimpleInjector.Scope.ThrowObjectDisposedException() bei SimpleInjector.Scope.RequiresInstanceNotDisposed() bei SimpleInjector.Scope.GetInstance[TService,TImplementation](ScopedRegistration2 registration) bei SimpleInjector.Scope.GetInstance[TService,TImplementation](ScopedRegistration2 registration, Scope scope) bei SimpleInjector.Advanced.Internal.LazyScopedRegistration2.GetInstance(Scope scope) bei lambda_method(Closure ) bei Glimpse.SimpleInjector.SimpleInjectorTab.CollectResolvedInstance(InitializationContext context, Func1 instanceProducer) bei SimpleInjector.Container.<>c__DisplayClass52_0.b__0() bei SimpleInjector.InstanceProducer.GetInstance() InnerException:

This one is thrown at:

SimpleInjector.dll!SimpleInjector.InstanceProducer.GetInstance() Unbekannt SimpleInjector.dll!SimpleInjector.Container.GetInstance(System.Type serviceType) Unbekannt idee5.Dispatcher.dll!SimpleInjector.SignalR.SimpleInjectorHubActivator.Create(Microsoft.AspNet.SignalR.Hubs.HubDescriptor descriptor) Zeile 11 C# Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.ResolveHub(string hubName) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hubs.HubDispatcher.CreateHub(Microsoft.AspNet.SignalR.IRequest request, Microsoft.AspNet.SignalR.Hubs.HubDescriptor descriptor, string connectionId, Microsoft.AspNet.SignalR.Hubs.StateChangeTracker tracker, bool throwIfFailedToCreate) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReceived(Microsoft.AspNet.SignalR.IRequest request, string connectionId, string data) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequestPostGroupRead.AnonymousMethod__7() Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod(System.Func func) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequestPostGroupRead.AnonymousMethod__6(string data) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Transports.WebSocketTransport.OnMessage(string message) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.WebSockets.DefaultWebSocketHandler.OnMessage(string message) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.WebSockets.WebSocketHandler.ProcessWebSocketRequestAsync(System.Net.WebSockets.WebSocket webSocket, System.Threading.CancellationToken disconnectToken, System.Func> messageRetriever, object state) Unbekannt mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext(object stateMachine) Unbekannt mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unbekannt mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unbekannt mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run() Unbekannt mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0() Unbekannt mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke() Unbekannt mscorlib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0() Unbekannt mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke() Unbekannt mscorlib.dll!System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation..cctor.AnonymousMethod__8_0(object state) Unbekannt System.Web.dll!System.Web.AspNetSynchronizationContext.Post.AnonymousMethod__0() Unbekannt System.Web.dll!System.Web.Util.SynchronizationHelper.SafeWrapCallback(System.Action action) Unbekannt System.Web.dll!System.Web.Util.SynchronizationHelper.QueueAsynchronous.AnonymousMethod__0(System.Threading.Tasks.Task _) Unbekannt mscorlib.dll!System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke() Unbekannt mscorlib.dll!System.Threading.Tasks.Task.Execute() Unbekannt mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj) Unbekannt mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unbekannt mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unbekannt mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) Unbekannt mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Unbekannt mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Unbekannt mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unbekannt mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

Another suspicious exception is:

SimpleInjector.ActivationException ist aufgetreten. HResult=-2146233088 Message=The SchedulerHub is registered as 'Hybrid Execution Context Scope / Web Request' lifestyle, but the instance is requested outside the context of a Hybrid Execution Context Scope / Web Request. Source=SimpleInjector StackTrace: bei SimpleInjector.Scope.GetScopelessInstance[TService,TImplementation](ScopedRegistration`2 registration) InnerException:

This one is thrown at:

SimpleInjector.dll!SimpleInjector.Scope.GetScopelessInstance(SimpleInjector.Lifestyles.ScopedRegistration registration) Unbekannt SimpleInjector.dll!SimpleInjector.Scope.GetInstance(SimpleInjector.Lifestyles.ScopedRegistration registration, SimpleInjector.Scope scope) Unbekannt SimpleInjector.dll!SimpleInjector.Advanced.Internal.LazyScopedRegistration.GetInstance(SimpleInjector.Scope scope) Unbekannt [Lightweightfunktion]
Glimpse.SimpleInjector.dll!Glimpse.SimpleInjector.SimpleInjectorTab.CollectResolvedInstance(SimpleInjector.Advanced.InitializationContext context, System.Func instanceProducer) Unbekannt SimpleInjector.dll!SimpleInjector.Container.ApplyResolveInterceptor.AnonymousMethod__0() Unbekannt SimpleInjector.dll!SimpleInjector.InstanceProducer.GetInstance() Unbekannt SimpleInjector.dll!SimpleInjector.Container.GetInstance(System.Type serviceType) Unbekannt idee5.Dispatcher.dll!SimpleInjector.SignalR.SimpleInjectorHubActivator.Create(Microsoft.AspNet.SignalR.Hubs.HubDescriptor descriptor) Zeile 11 C# Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.ResolveHub(string hubName) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hubs.HubDispatcher.CreateHub(Microsoft.AspNet.SignalR.IRequest request, Microsoft.AspNet.SignalR.Hubs.HubDescriptor descriptor, string connectionId, Microsoft.AspNet.SignalR.Hubs.StateChangeTracker tracker, bool throwIfFailedToCreate) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hubs.HubDispatcher.GetHubs.AnonymousMethod__39(Microsoft.AspNet.SignalR.Hubs.HubDescriptor descriptor) Unbekannt System.Core.dll!System.Linq.Enumerable.WhereSelectListIterator.MoveNext() Unbekannt System.Core.dll!System.Linq.Enumerable.WhereEnumerableIterator.MoveNext() Unbekannt mscorlib.dll!System.Collections.Generic.List.List(System.Collections.Generic.IEnumerable collection) Unbekannt System.Core.dll!System.Linq.Enumerable.ToList(System.Collections.Generic.IEnumerable source) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ExecuteHubEvent(Microsoft.AspNet.SignalR.IRequest request, string connectionId, System.Func action) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReconnected(Microsoft.AspNet.SignalR.IRequest request, string connectionId) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequestPostGroupRead.AnonymousMethod__5() Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod(System.Func func) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequestPostGroupRead.AnonymousMethod__4() Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Transports.ForeverTransport.ProcessReceiveRequest.AnonymousMethod__1c() Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Transports.ForeverTransport.ProcessMessages(Microsoft.AspNet.SignalR.Transports.ITransportConnection connection, System.Func initialize) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Transports.ForeverTransport.ProcessReceiveRequest(Microsoft.AspNet.SignalR.Transports.ITransportConnection connection) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Transports.ForeverTransport.ProcessRequestCore.AnonymousMethod__e(Microsoft.AspNet.SignalR.Transports.ForeverTransport t, Microsoft.AspNet.SignalR.Transports.ITransportConnection c) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod(System.Func func, System.__Canon arg1, System.__Canon arg2) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.TaskAsyncHelper.Then(System.Threading.Tasks.Task task, System.Func successor, Microsoft.AspNet.SignalR.Transports.ForeverTransport arg1, Microsoft.AspNet.SignalR.Transports.ITransportConnection arg2) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Transports.ForeverTransport.ProcessRequestCore(Microsoft.AspNet.SignalR.Transports.ITransportConnection connection) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Transports.WebSocketTransport.ProcessRequest.AnonymousMethod__2(Microsoft.AspNet.SignalR.Hosting.IWebSocket socket) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Owin.OwinWebSocketHandler.RunWebSocketHandler.AnonymousMethod__0() Unbekannt mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Startc__DisplayClass1.<b__0>d__3 stateMachine) Unbekannt Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Owin.OwinWebSocketHandler.RunWebSocketHandler.AnonymousMethod__0() Unbekannt mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke() Unbekannt mscorlib.dll!System.Threading.Tasks.Task.Execute() Unbekannt mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj) Unbekannt mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unbekannt mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unbekannt mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) Unbekannt mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Unbekannt mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Unbekannt mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unbekannt mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Unbekannt

Both are caught. And I suspect that's the reason nothing seems to happen and my hub methods are not called.

After some try'n'error sessions I ended up with this container configuration.

    public static Container GetInitializeContainer(IAppBuilder app) {
    // configure AutoMapper
    MapperConfiguration mapperConfig = ConfigureMappings();

    // Create the container as usual.
    var container = new Container();
    ScopedLifestyle hybrid = Lifestyle.CreateHybrid(
        () => container.GetCurrentExecutionContextScope() != null,
        new ExecutionContextScopeLifestyle(),
        new WebRequestLifestyle());
    container.Options.DefaultScopedLifestyle = hybrid;

    // Registering the types
    container.RegisterSingleton(() => mapperConfig.CreateMapper());
    container.RegisterSingleton(app);
    container.RegisterPerWebRequest<IUrlHelperProvider, UrlHelperProvider>();
    // register the singleton services
    container.RegisterSingleton<ICacheService>(new CacheService());
    container.RegisterSingleton<ILoggingService, LoggingService>();

    // register application services
    // get the assembly containing the services 
    Assembly repositoryAssembly = typeof(CompanyService).Assembly;
    // get the services namespace
    string @namespace = typeof(CompanyService).Namespace;
    // register all interfaces in the assembly besides the singletons
    var registrations =
        from type in repositoryAssembly.GetExportedTypes()
        where type.Namespace == @namespace
        where type.GetInterfaces().Any(i => i.Name.EndsWith(value: "Service") &&
            i.Name != nameof(ICacheService) && i.Name != nameof(ILoggingService))
        select new { Service = type.GetInterfaces().Single(i => i.Name.EndsWith(value: "Service")), Implementation = type };

    foreach (var reg in registrations) {
        container.Register(reg.Service, reg.Implementation, new WebRequestLifestyle());
    }

    container.RegisterPerWebRequest<ApplicationUserManager>();
    container.RegisterPerWebRequest<IUserStore<IdentityUser, Guid>>(() => new UserStore());
    container.RegisterInitializer<ApplicationUserManager>(manager => InitializeUserManager(manager, app));
    // register the role manager
    container.RegisterPerWebRequest<ApplicationRoleManager>();
    container.RegisterPerWebRequest<IRoleStore<IdentityRole, Guid>>(() => new RoleStore());
    container.RegisterInitializer<ApplicationRoleManager>(manager => InitializeRoleManager(manager));

    container.Register<Hubs.SchedulerHub, Hubs.SchedulerHub>(Lifestyle.Scoped);
    // register the sign in manager
    container.RegisterPerWebRequest<ApplicationSignInManager>();
    container.RegisterPerWebRequest(() => AdvancedExtensions.IsVerifying(container)
            ? new OwinContext(new Dictionary<string, object>()).Authentication
            : HttpContext.Current.GetOwinContext().Authentication);

    // Register all controllers and filters. Including those in MVC areas
    container.RegisterMvcControllers();
    container.RegisterMvcIntegratedFilterProvider();

    // register OWIN
    app.Use(async (context, next) => {
        using (container.BeginExecutionContextScope()) {
            CallContext.LogicalSetData(name: "IOwinContext", data: context);
            await next();
        }
    });
    container.RegisterSingleton<IOwinContextProvider>(new CallContextOwinContextProvider());

    return container;
}

My hub activator:

    public class SimpleInjectorHubActivator : IHubActivator {
    public SimpleInjectorHubActivator(Container container) {
        _container = container;
    }

    public IHub Create(HubDescriptor descriptor) {
        return (IHub) _container.GetInstance(descriptor.HubType);
    }

    private readonly Container _container;
}

My hub dispatcher:

public class SimpleInjectorHubDispatcher : HubDispatcher {
    public SimpleInjectorHubDispatcher(Container container, HubConfiguration configuration)
        : base(configuration) {
        _container = container;
    }

    protected override Task OnConnected(IRequest request, string connectionId) {
        return Invoke(() => base.OnConnected(request, connectionId));
    }

    protected override Task OnReceived(IRequest request, string connectionId, string data) {
        return Invoke(() => base.OnReceived(request, connectionId, data));
    }

    protected override Task OnDisconnected(IRequest request, string connectionId,
        bool stopCalled) {
        return Invoke(() => base.OnDisconnected(request, connectionId, stopCalled));
    }

    protected override Task OnReconnected(IRequest request, string connectionId) {
        return Invoke(() => base.OnReconnected(request, connectionId));
    }

    private async Task Invoke(Func<Task> method) {
        using (_container.BeginExecutionContextScope())
            await method();
    }

    private readonly Container _container;
}

How can I prevent this exception and get my hub methods being invoked?

2
What's the exception message in English?Steven
And please post the complete stack trace (with inner exception details).Steven
Hi Steven. I added an english version and the exception appearing beofre in the diagnoe tools.bdongus
Sorry for the delay. Had to figure out how I can get more details about the excecptions.bdongus
You left out the inner exception details. Please add those.Steven

2 Answers

2
votes

From the stack trace I see that the default HubDispatcher is invoked, not your custom SimpleInjectorHubDispatcher. This means that no scope is applied and this is probably the reason why you are getting the message "the instance is requested outside the context of a Hybrid Execution Context Scope / Web Request."

You should register your SimpleInjectorHubDispatcher as follows: I think the error is in the following line:

var dispatcher = new SimpleInjectorHubDispatcher(container, config);
config.Resolver.Register(typeof(HubDispatcher), dispatcher);
1
votes

Thanks to Stevens chat support and some deep digging I found the flaw. I mixed up the life styles of the hub and the used services.

The hard part was to gather any details about the silently failing SignalR call. If anyone else runs into such a situation I would like to share two hints on how to gather more information:

  • Have a close look at your debug output and look for suspicious exceptions.
  • Tell Visual Studio to break if those occur.

That way you can get hold of the stack trace, inner exception, etc. Otherwise you won't find the reason. In my case I monitored SimpleInjector.ActivationException and Steven helped me to find the reason.