4

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

Leo
  • 41
  • 1
  • 4
  • Btw - which version of SignalR are you running? I will look into your code in details tomorrow, but I'm pretty sure something's not right here. Please correct the pasted code - last line in the first box seems orphaned:) – Piotr Szmyd Sep 25 '12 at 23:02
  • Thanks for the reply. I'm using SignalR version 0.5.3 and If I change InstancePerHttpRequest to InstancePerLifetimeScope, it works fine unfortunately, I can no longer add a new record to the database (using EF as data layer). Any help would be greatly appreciated, thanks! – Leo Sep 26 '12 at 18:14

2 Answers2

3

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 });
    }
}
sky-dev
  • 6,190
  • 2
  • 33
  • 32
1

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

Community
  • 1
  • 1
dove
  • 20,469
  • 14
  • 82
  • 108
  • Thanks for the speedy reply. Unfortunately, I'm still running into the same error message. – Leo Sep 25 '12 at 13:51