Closed GoogleCodeExporter closed 8 years ago
Can you please provide some details?
Original comment by alex.meyergleaves
on 16 Mar 2013 at 12:40
According to the Signalr web site:
https://github.com/SignalR/SignalR/wiki/Extensibility
I download the zip and install the .dll then do
http://code.google.com/p/autofac/downloads/detail?name=Autofac.SignalR.3.0.0.zip
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
//Register Context
builder.Register(c => new myContext()).As<IUnitOfWork>().InstancePerLifetimeScope();
//Repositories
builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IBaseRepository<>)).InstancePerHttpRequest();
//Service Layer
builder.RegisterType<PersonService>().As<IPersonService>().InstancePerHttpRequest();
//more services here
builder.RegisterType<ChatHub>();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalHost.DependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
RouteTable.Routes.MapHubs();
}
}
but I get an error of
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in
which the instance was requested. This generally indicates that a component
registered as per-HTTP request is being requested by a SingleInstance()
component (or a similar scenario.) Under the web integration always request
dependencies from the DependencyResolver.Current or
ILifetimeScopeProvider.RequestLifetime, never from the container itself.
I have tried changing
builder.RegisterType<ChatHub>();
to
builder.RegisterType<ChatHub>().InstancePerLifetimeScope();
But I get the same instance, if I dontt register the hub, and don't have a
parameterless constructor then it simply doesn't do anything.
Original comment by EnenDave...@gmail.com
on 16 Mar 2013 at 6:50
I am guessing that the ChatHub must have dependencies that are registered as
InstancePerHttpRequest. Unfortunately, it is not possible to create a lifetime
scope per hub invocation (I have confirmed this with David Fowler), so no
'AutofacWebRequest' lifetime scope is available to the hub. I am going to
change the RegisterHubs method to register the hubs as ExternallyOwned to
prevent the disposer in the root lifetime scope holding onto the instances.
SignalR will call Dispose on the hub but you have to dispose any dependencies
yourself because there will be no per-hub lifetime scope to do it for you.
Original comment by alex.meyergleaves
on 17 Mar 2013 at 8:21
Thanks for the info, so if I set it up now in the same way it will work but I
need to sort out my own disposal? or when will the update happen?
Can I manually add instance of service to a paramaterless contructor something
like:
private IPersonService;
public ChatHub()
{
IPersonService = //do something here to get an insatnce of my personservice
using autofac
}
Original comment by EnenDave...@gmail.com
on 18 Mar 2013 at 9:30
You can still perform constructor injection but will need to perform your own
disposal. Whether or not you need actual dispose the instance depends on how
its lifetime is configured and would be easy to get wrong. Also, if you didn't
mark the components are ExternallyOwned the disposer on the root lifetime scope
would hold onto them.
An alternative option is to inject the ILifetimeScope into the constructor of
the hub, and create a new child lifetime scope to resolve your components from.
Then in the Dispose method of the hub, you can call the Dispose method on the
child lifetime scope and clean up.
public class MyHub : Hub
{
readonly ILifetimeScope _hubLifetimeScope;
readonly IDependency _dependency;
public MyHub(ILifetimeScope lifetimeScope)
{
_hubLifetimeScope = lifetimeScope.BeginLifetimeScope();
_dependency = _hubLifetimeScope.Resolve<IDependency>();
}
// Use the dependency in a hub method.
protected override void Dispose(bool disposing)
{
if (disposing && _hubLifetimeScope != null)
_hubLifetimeScope.Dispose();
base.Dispose(disposing);
}
}
I will create a SignalR page on the wiki and add some notes. It would be nice
if there was a better solution but SignalR currently doesn't have the hooks. I
have commented on a SignalR issue that raises essentially the same concern.
https://github.com/SignalR/SignalR/issues/863#issuecomment-15042473
Original comment by alex.meyergleaves
on 18 Mar 2013 at 1:40
Thanks, I am trying the second approach, I will hopefully wait for the new
updates to resolve the issue until i do the full changes.
However I can't get it to work, I am assuming I need to register the hub, with
in the container eg
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
//Register Context
builder.Register(c => new myContext()).As<IUnitOfWork>().InstancePerLifetimeScope();
//Repositories
builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IBaseRepository<>)).InstancePerHttpRequest();
//Service Layer
builder.RegisterType<PersonService>().As<IPersonService>().InstancePerHttpRequest();
//more services here
builder.RegisterType<ChatHub>();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
RouteTable.Routes.MapHubs();
}
However not matter what I set builder.RegisterType<ChatHub>(); to, when I try
and use the sub in a chat like send, nothing happens. I have tried
builder.RegisterType<ChatHub>().InstancePerLifetimeScope(); and everything else
I can think of but still nothing.
Thanks for the help, and sorry for being such a noob
Original comment by EnenDave...@gmail.com
on 18 Mar 2013 at 10:03
There is a separate AutofacDependencyResolver for SignalR that needs to be
assigned to GlobalHost.DependencyResolver. I added a wiki page that might help
you get started.
https://code.google.com/p/autofac/wiki/SignalRIntegration
No problem with the help. I should have put some doco up earlier.
Original comment by alex.meyergleaves
on 18 Mar 2013 at 11:56
Thanks I am still really having troubles and getting the same errors, I am
using ASP.NET MVC.
I have 1 question which might not help, but do I set up one build and container
for the normal MVC project and a seperate one for the hubs? or should they be
in the same one?
Also there is no extension method builder.RegisterHubs.
Original comment by EnenDave...@gmail.com
on 20 Mar 2013 at 11:28
Hi Just to add thanks again for the help, I got it working, but in the info
guide I think you need to make it clear this has to be a different setup for
the hub, and the normal MVC dependecy injection otherwise you still end up with
the same errors as the mix of .InstancePerHttpRequest() and .ExternallyOwned()
causes errors, I am not sure if thats the correct way to do it, but it is
working.
Original comment by EnenDave...@gmail.com
on 20 Mar 2013 at 11:40
Thanks for the update and I'm glad you got it working. I wish it possible to
provide lifetime scopes in SignalR and things weren't so tricky right now.
Keeping things separate is certainly a decent option. If I can't think of a
cleaner option I'll update the wiki that recommendation.
Original comment by alex.meyergleaves
on 20 Mar 2013 at 12:24
Just wanted to say thanks again for the help :-)
Original comment by EnenDave...@gmail.com
on 20 Mar 2013 at 1:15
Original issue reported on code.google.com by
EnenDave...@gmail.com
on 16 Mar 2013 at 10:57