I'm using autofac on my current Asp project and everything works fine until i decided to use dependancy injection in a signalR Hub
here's my startup class
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.RegisterType<DbFactory>().As<IDbFactory>().InstancePerLifetimeScope();
//builder.RegisterHubs(Assembly.GetExecutingAssembly());
builder.RegisterType<DiscussionHub>();
// Repositories
builder.RegisterAssemblyTypes(typeof(LanguagesRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces().InstancePerRequest();
// Services
builder.RegisterAssemblyTypes(typeof(LanguageService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerRequest();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
var config = new HubConfiguration
{
Resolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container)
};
app.UseAutofacMiddleware(container);
AutoMapperConfiguration.Configure();
app.MapSignalR("/signalr",config);
}
}
and here's my Hub
public class DiscussionHub : Hub
{
private readonly IDiscussionService _discussionService;
public DiscussionHub(IDiscussionService discussionService)
{
_discussionService = discussionService;
}}
the error is that i'm getting no parameterless constructor on my Hub? any suggestion ?!
You should register your hub ExternallyOwned
it should manage lifetimescope by itself. That's mean autofac will not disposed them.
Second, everything will be resolved from root container in your hub. That's mean Per Dependency
or Per LifeTimeScope
will live with your hub(forever with app). So you should manage lifetime in your hub.
Even if we manage life time in your hub, Per Request
will not be supported. Because of this, when we create new lifetimescope, we will create it with AutofacWebRequest
tag. That way, we can resolve your Per Request
instance. But pay attention this instance will be totaly different with other instance in normal request lifetimescope.
Your Hub should be like this:
public class DiscussionHub : Hub
{
private readonly ILifetimeScope _hubLifetimeScope;
private readonly IDiscussionService _discussionService;
public MyHub(ILifetimeScope lifetimeScope)
{
// Create a lifetime scope for the hub.
_hubLifetimeScope = lifetimeScope.BeginLifetimeScope("AutofacWebRequest");
// Resolve dependencies from the hub lifetime scope.
_discussionService = _hubLifetimeScope.Resolve<IDiscussionService>();
}
protected override void Dispose(bool disposing)
{
// Dipose the hub lifetime scope when the hub is disposed.
if (disposing && _hubLifetimeScope != null)
{
_hubLifetimeScope.Dispose();
}
base.Dispose(disposing);
}
}
Your register should be like this:
.
.
builder.RegisterType<DiscussionHub>().ExternallyOwned();
var container = builder.Build();
GlobalHost.DependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
.
.
Owin Integration:
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
// STANDARD SIGNALR SETUP:
// Get your HubConfiguration. In OWIN, you'll create one
// rather than using GlobalHost.
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);
// OWIN SIGNALR SETUP:
// Register the Autofac middleware FIRST, then the standard SignalR middleware.
app.UseAutofacMiddleware(container);
app.MapSignalR("/signalr", config);
}
Check more detail.