Christoph Adamakis
Christoph Adamakis

Reputation: 883

autofac owin wep api and signalr

I am using autofac with web api and now I want to add signalr as well. My current configuration is as follows

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        WebApiConfig.Register(config);
        // Register your Web Api controllers.
        IoC.Instance.RegisterApiControllers(Assembly.GetExecutingAssembly());
        IoC.Instance.RegisterWebApiModelBinders(Assembly.GetExecutingAssembly());
        IoC.Instance.RegisterWebApiModelBinderProvider();

        //Set Autofac to be the Dependency Resolver both for Web Api and for SignalR
        config.DependencyResolver = new AutofacWebApiDependencyResolver(IoC.Instance.GetComponentsContainer());
        // Register the Autofac middleware FIRST, then the Autofac Web API middleware,
        // and finally the standard Web API middleware.
        app.UseAutofacMiddleware(IoC.Instance.GetComponentsContainer());
        app.UseAutofacWebApi(config);
        app.UseWebApi(config);
        //Signalr
        app.Map("/signalr", map =>
        {
            map.UseCors(CorsOptions.AllowAll);
            //   map.MapSignalR("/signalr", hubconfig);
            var hubConfiguration = new HubConfiguration
            {
            };
            map.RunSignalR(hubConfiguration);
        });

    }
}

IoC Class as follows

public class IoC : ContainerBuilder
{
    private readonly static IoC _instance = new IoC();
    private static object _lock;
    private IContainer _componentsContainer;
    public static IoC Instance
    {
        get
        {
            return _instance;
        }
    }
    public IContainer GetComponentsContainer()
    {
        if (_componentsContainer == null)
        {
            lock (_lock)
            {
                if (_componentsContainer == null)
                    _componentsContainer = this.Build();
            }
        }
        return _componentsContainer;
    }
    public T Resolve<T>() where T : class
    {
        return GetComponentsContainer().Resolve<T>();
    }
    public ILifetimeScope BeginLifetimeScope()
    {
        return GetComponentsContainer().BeginLifetimeScope();
    }
    private IoC()
    {
        _lock = new object();
        ConfigureDependencies();
    }

    private void ConfigureDependencies()
    {
        var connectionString = ConfigurationManager.ConnectionStrings["DBConnectionStringName"].ConnectionString;
        this.Register(c => new SqlConnection(connectionString)).As<IDbConnection>().InstancePerRequest();// InstancePerLifetimeScope();

        //Database Connection OrmLite
        OrmLiteConfig.DialectProvider = SqlServerDialect.Provider;
        //Register Repositories
        this.RegisterType<Repository>().As<IRepository>().InstancePerRequest();//.InstancePerLifetimeScope();
        // Register Services
        this.RegisterType<UserService>().As<IUserService>().InstancePerRequest();//.InstancePerLifetimeScope();
        this.RegisterType<TokenService>().As<ITokenService>().InstancePerRequest();//.InstancePerLifetimeScope();
    }

}

As it is obvious I haven't added dependency injection for SignalR. I want to add in order to have hub constructors like this

private readonly ITokenService _tokenService;
    private readonly ILifetimeScope _hubLifetimeScope;



    public JobHub(ILifetimeScope lifetimeScope)
    {
        // Create a lifetime scope for the hub.
        _hubLifetimeScope = lifetimeScope.BeginLifetimeScope();
        // Resolve dependencies from the hub lifetime scope.
        _tokenService = _hubLifetimeScope.Resolve<ITokenService>();
    }

Any Ideas on how to do this?

Upvotes: 1

Views: 527

Answers (2)

Christoph Adamakis
Christoph Adamakis

Reputation: 883

After some investigation I found the Solution. In IoC Class and in method ConfigureDependencies() I added the following line at the end this.RegisterHubs(Assembly.GetExecutingAssembly());. The Configuration method in StartUp now is as follows

   public void Configuration(IAppBuilder app)
    {
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
        // Get your HttpConfiguration. In OWIN, you'll create one
        // rather than using GlobalConfiguration.

        var config = new HttpConfiguration();
        WebApiConfig.Register(config);
        //HubConfiguration
        var hubconfig = new HubConfiguration();
        // Register your Web Api controllers.
        IoC.Instance.RegisterApiControllers(Assembly.GetExecutingAssembly());
        IoC.Instance.RegisterWebApiModelBinders(Assembly.GetExecutingAssembly());
        IoC.Instance.RegisterWebApiModelBinderProvider();

        //Set Autofac to be the Dependency Resolver both for Web Api and for SignalR
        config.DependencyResolver = new AutofacWebApiDependencyResolver(IoC.Instance.GetComponentsContainer());
        hubconfig.Resolver = new AutofacDependencyResolver(IoC.Instance.GetComponentsContainer());
        // Register the Autofac middleware FIRST, then the Autofac Web API middleware,
        // and finally the standard Web API middleware.
        app.UseAutofacMiddleware(IoC.Instance.GetComponentsContainer());
        app.UseAutofacWebApi(config);
        app.UseWebApi(config);
        //Signalr
        app.Map("/signalr", map =>
        {
            map.UseCors(CorsOptions.AllowAll);
            map.RunSignalR(hubconfig);
        });

    }

And now the tricky thing My hub Constructor has to become like this

 public JobHub(ILifetimeScope lifetimeScope)
    {
        // Create a lifetime scope for the hub.
        _hubLifetimeScope = lifetimeScope.BeginLifetimeScope("AutofacWebRequest");
        // Resolve dependencies from the hub lifetime scope.
        _tokenService = _hubLifetimeScope.Resolve<ITokenService>();
    }

I don't how how that thing worked, but it worked. Any suggestions whether this is good or bad configuration are welcome!

Upvotes: 2

JEV
JEV

Reputation: 2504

Your Startup.cs should look like this prior to custom integration

  public class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      var builder = new ContainerBuilder();
      var config = new HubConfiguration();

      // Register your SignalR hubs.
      builder.RegisterHubs(Assembly.GetExecutingAssembly());

      // Set the dependency resolver to be Autofac.
      var container = builder.Build();
      config.Resolver = new AutofacDependencyResolver(container);

      app.UseAutofacMiddleware(container);
      app.MapSignalR("/signalr", config);
    }
  }

Check out the docs on Autofacs site for more info: http://docs.autofac.org/en/latest/integration/signalr.html#owin-integration

Upvotes: 1

Related Questions