Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR Dependency Injection for ASP.NET Core v2.0 using Autofac

Is it possible to use dependency injection to inject dependencies into SignalR on ASP.NET Core v2.0?

Assuming the following hub and dependency:

public MyHub : Hub {

    private readonly IMyDependency dependency;

    public MyHub(IMyDependency dependency) {
        this.dependency = dependency;
    }
}

public void MyDependency : IDependency
{
    public void MyMethod() {
        Console.WriteLine("I'm a dependency!");
    }
}

I've scoured a bit of the web and there isn't anything obvious out there. I found this tutorial which at first seemed quite promising until I realised it was for Microsoft.AspNetCore.SignalR.Server which didn't ship in the end.

At the moment I have the following setup using Autofac and it's not working:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddSignalR();

        // Configue Autofac
        var containerBuilder = new ContainerBuilder();

        containerBuilder.RegisterModule<MyModule>();

        // Configure SignalR hubs for dependency injection
containerBuilder.RegisterSignalRHubs(typeof(Startup).GetTypeInfo().Assembly);

        containerBuilder.Populate(services);
        var container = containerBuilder.Build();
        return new AutofacServiceProvider(container);
    }
}

public static class AutoFacExtensions
{
    public static IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle> RegisterSignalRHubs(this ContainerBuilder builder, params Assembly[] assemblies)
    {
        return builder.RegisterAssemblyTypes(assemblies)
            .Where(t => typeof(IHub).IsAssignableFrom(t))
            .ExternallyOwned();
    }
}

public class MyModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<MyDependency>().As<IMyDependency>();
    }
}

It looks like the IHub interface doesn't exist anymore. I tried IHubContext<MyHub> in the hope that this might work with the latest version but sadly not.

When I have dependencies in my hub's constructor, the hub isn't created despite all of the dependencies registered with Autofac.

How can I achieve this with the lastest version 1.0.0.0-alpha2-final?

like image 555
Luke Avatar asked Jan 06 '18 20:01

Luke


People also ask

How do I integrate Autofac with SignalR?

Along with this documentation that’s Autofac specific, you may also be interested in the Microsoft documentation on SignalR and dependency injection. To get Autofac integrated with SignalR you need to reference the SignalR integration NuGet package, register your hubs, and set the dependency resolver.

How does Dependency Injection work in SignalR?

If you have questions that are not directly related to the tutorial, you can post them to the ASP.NET SignalR forum or StackOverflow.com. Dependency injection is a way to remove hard-coded dependencies between objects, making it easier to replace an object's dependencies, either for testing (using mock objects) or to change run-time behavior.

How to create signalrwebpack using ASP NET Core?

Use the File > New > Project menu option and choose the ASP.NET Core Web Application template. Name the project SignalRWebPack, and select Create. Select .NET Core from the target framework drop-down, and select ASP.NET Core 2.2 from the framework selector drop-down.

How to integrate Autofac with ASP NET Core?

The core of the integration is the AutofacServiceProviderFactory. It enables Autofac as DI container in your ASP.NET Core Application. 3. Add a ConfigureContainer method to Startup class. ConfigureServices method is called by .NET Core at application startup time to register additional services.


1 Answers

The example given in the question does work with version 1.0.0.0-alpha2-final of Microsoft.AspNetCore.SignalR with one slight tweak, use Hub rather than the now non-existent IHub.

public static class AutoFacExtensions
{
    public static IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle> RegisterSignalRHubs(this ContainerBuilder builder, params Assembly[] assemblies)
    {
        // typeof(Hub), not typeof(IHub)
        return builder.RegisterAssemblyTypes(assemblies)
            .Where(t => typeof(Hub).IsAssignableFrom(t))
            .ExternallyOwned();
    }
}

Ensure that all of your dependencies are satisfied by assigning them to a controller. I'm not sure at this point how to troubleshoot broken dependencies when injecting into a SignalR hub with this method.

like image 154
Luke Avatar answered Nov 08 '22 06:11

Luke