Obscured
Obscured

Reputation: 291

What would the Autofac equivalent to this Ninject code be?

On the following page: http://www.asp.net/signalr/overview/signalr-20/extensibility/dependency-injection

Near the bottom (just below the text "RegisterHubs.Start") there is a piece of Ninject code that I am trying to reproduce using Autofac.

So far I have succeeded in giving myself a headache, but not much else. I have scoured the Autofac wiki, and the web for some help. Though, I am sure I probably missed some tidbit of information.

Update: Here is the relevant Ninject code on the page.

public static class RegisterHubs
{
    public static void Start()
    {
        var kernel = new StandardKernel();
        var resolver = new NinjectSignalRDependencyResolver(kernel);

        kernel.Bind<IStockTicker>()
            .To<Microsoft.AspNet.SignalR.StockTicker.StockTicker>()
            .InSingletonScope();

        kernel.Bind<IHubConnectionContext>().ToMethod(context =>
                resolver.Resolve<IConnectionManager>().
                    GetHubContext<StockTickerHub>().Clients
            ).WhenInjectedInto<IStockTicker>();

        var config = new HubConfiguration()
        {
            Resolver = resolver
        };

        App.MapSignalR(config);
    }
}

Update 2: Thought I would also add the objects trying to be composed.

public class StockTickerHub : Hub
{
    private readonly IStockTicker _stockTicker;

    public StockTickerHub(IStockTicker stockTicker) { }
}

public class StockTicker
{
    public StockTicker(IHubConnectionContext clients) { }
}

Upvotes: 12

Views: 3216

Answers (1)

khellang
khellang

Reputation: 18102

Autofac does not have an equivalent of the WhenInjectedInto method. However, you could accomplish the same using named parameters.

Try something like this

using Autofac.Integration.SignalR;
using Microsoft.AspNet.SignalR.StockTicker;

public static class RegisterHubs
{
    public static void Start() 
    {
        var builder = new ContainerBuilder();

        builder.RegisterType<StockTicker>()
            .WithParameter(ResolvedParameter.ForNamed("StockTickerContext"))
            .As<IStockTicker>()
            .SingleInstance();

        builder.Register(c => GlobalHost.DependencyResolver.Resolve<IConnectionManager>().GetHubContext<StockTickerHub>().Clients)
            .Named<IHubConnectionContext>("StockTickerContext");

        var container = builder.Build();

        var resolver = new AutofacDependencyResolver(container);

        var config = new HubConfiguration { Resolver = resolver };

        App.MapSignalR(config);
    }
}

Note: The AutofacDependencyResolver comes from Autofac.Integration.SignalR.

Update: Ah, I missed a tiny detail from the linked page; the factory function for the IHubConnectionContext is using the resolver to get the IConnectionManager, and not the container itself (of course the container won't know about a IConnectionManager). I switched to use the default dependency resolver (GlobalHost.DependencyResolver) to get the IConnectionManager instead. That should work.

Upvotes: 12

Related Questions