Search code examples
c#asp.net-mvcdependency-injectionsignalrdependency-resolver

Simple Injector registration problem in SignalR


I set DI in my Controller as shown below and tied to register IHubContext as it seen on

Controller:

public class DemoController : Controller
{
    private IHubContext<DemoHub> context;

    public DemoController(IHubContext<DemoHub> context)
    {
        this.context = context;
    }
}


Global.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    var container = new Container();
    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();



    container.Register<IHubContext, IHubContext>(Lifestyle.Scoped);

    // or 

    container.Register<IHubContext>(Lifestyle.Scoped);

    // code omitted
}

But when I debug my app, encounter "System.ArgumentException: 'The given type IHubContext is not a concrete type. Please use one of the other overloads to register this type. Parameter name: TImplementation'" error. So, how can I register IHubContext properly?


Solution

  • Since ASP.NET MVC doesn't have built in dependency injection for SignalR hub context you have to obtain a context instance using GlobalHost.ConnectionManager. With this you can register a dependency with your container that creates IHubContext instance. Considering you have typed hub

    public class DemoHub : Hub<ITypedClient>
    {
    }
    

    and interface

    public interface ITypedClient
    {
        void Test();
    }
    

    register dependency as the following

    container.Register<IHubContext<ITypedClient>>(() =>
    {
        return GlobalHost.ConnectionManager.GetHubContext<DemoHub, ITypedClient>();
    }, Lifestyle.Scoped);
    

    And the controller should look like

    public class DemoController : Controller
    {
        private IHubContext<ITypedClient> context;
    
        public DemoController(IHubContext<ITypedClient> context)
        {
            this.context = context;
        }
    }