Reputation: 883
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
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
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