Leo
Leo

Reputation: 41

Autofac + SignalR

I'm completely new to both autofac and singalR libraries, so please be easy on me! I've got the following code in bootstrapper which works on its own without signalR.

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();

builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerHttpRequest();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();

builder.RegisterAssemblyTypes(typeof(adminRepository).Assembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerHttpRequest();

builder.RegisterAssemblyTypes(typeof(adminService).Assembly).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerHttpRequest();

builder.RegisterFilterProvider();
IContainer container = builder.Build();

DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));

Above code works just fine but after registering my Hub with this below code, it just doesn't work.

builder.RegisterType<Chat>().InstancePerLifetimeScope();

builder.RegisterFilterProvider();
IContainer container = builder.Build();

DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));

SignalR.IDependencyResolver resolver = new SignalR.Autofac.AutofacDependencyResolver(container);
GlobalHost.DependencyResolver = resolver;
RouteTable.Routes.MapHubs(resolver);

I'm using SignalR dependency resolver binding to Autofac from this (https://github.com/pszmyd/SignalR.Autofac).

I've got a simple hub like this,

public class Chat : Hub
{
    private readonly IadminService adminService;
    public Chat(IadminService adminService)
    {
        this.adminService = adminService;
    }

    public void Send(string message)
    {
        Clients.addMessage(message);
    }
}

This is the error I've got when I tried to use DI to the hub.

"No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested."

No matter what I do, I can't seem to get it working and I'd be grateful if someone could please tell me what's wrong with the code above.

Many Thanks Leo

Upvotes: 4

Views: 2769

Answers (2)

sky-dev
sky-dev

Reputation: 6258

For an ASP.NET application hosted in IIS add this to Application_Start:

var container = AutofacConfig.BuildContainer();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
var signalRDependencyResolver = new SignalRAutofacDependencyResolver(container);
// old SignalR 1.0 way - routes.MapHubs(signalRDependencyResolver);
RouteTable.Routes.MapHubs(new HubConfiguration { Resolver = signalRDependencyResolver });

You may find the SignalRAutofacDependencyResolver here.

Example hub injecting an ISecurity service:

public class ExampleHub : Hub
{
    private static int _count = 0;

    private readonly ISecurity _security;
    public ExampleHub(ISecurity security)
    {
        _security = security;
    }

    public void GetCount()
    {
        _count++;
        Clients.All.SetCount(_count);         
    }
}

This also works with SignalR self host release. Just use a startup class like this:

// These are static variables in Program.cs - Probably a better way to do this
_container = AutofacConfig.BuildContainer();
_webServer = WebApp.Start<WebServerStartup>("http://localhost:8080");

public class WebServerStartup
{
    private readonly SignalRAutofacDependencyResolver _signalRDependencyResolver;

    public WebServerStartup()
    {
        _signalRDependencyResolver = new SignalRAutofacDependencyResolver(_container); 
    }

    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR(new HubConfiguration { Resolver = _signalRDependencyResolver });
    }
}

Upvotes: 3

dove
dove

Reputation: 20674

After setting the DependencyResolver do you still need to pass it to MapHubs, that is try this instead:

GlobalHost.DependencyResolver = resolver;

RouteTable.Routes.MapHubs();

I know SignalR but never used Autofac but it may be worth looking at these answers for details on possible Autofac issue:

How to resolve Autofac InstancePerHttpRequest

Autofac, ASP.NET MVC 3 httpRequest scope and AutoMapper: No scope with a Tag matching 'httpRequest' is visible

Upvotes: 1

Related Questions