SignalR with IoC (Castle Windsor) - which lifetime for hubs? - inversion-of-control

I'm just starting out with SignalR, and have created a custom resolver for SignalR, so I can use Castle Windsor to inject dependencies via hub constructors.
I kind of assumed that I would only need to register the dependencies, but I found that it was also necessary to register the hubs themselves before my app would work. Is this expected? If so, what lifetime should I use for hubs?

By default SignalR does not register each hub with the dependency resolver. Instead it uses an IAssemblyLocator to find available assemblies that might contain SignalR Hubs. Then the IHubDescriptorProvider searches through all the available assemblies for Hubs and creates HubDescriptors.
Lastly, the IHubActivator takes a HubDescriptor and returns a newly instantiated SignalR hub (using Activator.CreateInstance) unless the Hub type associated with the HubDescriptor has been registered with the dependency resolver. In the latter case, the Hub returned from the IHubActivator will be taken directly from the dependency resolver.
Typically SignalR hubs are ephemeral meaning that they get created and destroyed for each Hub method invocation. This means that if you register your Hub with SignalR's dependency resolver, you should make sure that a new Hub instance is returned each time SignalR resolves the Hub type.
I strongly advise against registering a singleton Hub for several reasons:
Hub methods can be called in parallel. When this happens, Hub.Context can be overridden as part of the setup for another method call. This can lead to really subtle bugs. For example, with a singleton Hub, the following code might add a connection other than the caller to a group (which could obviously be a big security issue):
[Authorize(Roles="Admin")]
public async Task JoinAdminGroup()
{
await Groups.Add(Context.ConnectionId, "admin");
}
Hub.Dispose will be called after each activation. If you keep returning the same Hub, it's Dispose method will be repeatedly called. This probably won't affect you unless you implement Dispose on your Hubs, since the default Dispose implementation currently no-ops.
IIS recycles AppDomains. When this happens, you will be forced to reinstantiate your Hub anyway. Remember, SignalR will automatically reestablish active connections after your app becomes unavailable for a short period of time (as is the case with an AppDomain recycle), so you can very well have a newly instantiated Hub dealing with pre-existing connections even if you register your Hub as a Singleton with the dependency resolver.
https://github.com/SignalR/SignalR/blob/2.0.1/src/Microsoft.AspNet.SignalR.Core/DefaultDependencyResolver.cs#L79

Related

AutoFac Module gets not disposed

I have an autofac module which implements IDisposable. The module is registerd with the containerBuilder.RegisterModule<> method and it gets resolved during container.Build. But: Dispose is not called on the module when container gets disposed.
Is this a bug, or do i miss something?
I have reproduced this with Autofac 4.6.2 and 4.8.1, didn't test other versions between.
Modules are not meant to be disposed. The link between Autofac and disposable components is fulfilled by the ILifetimeScope implementations.
A module is basically a box with a Load method, that gets executed once.
When the Load method completes, you must be done with the module.
So, if you have any resource to be kept alive and disposed afterwards, it should be kept alive (and disposed) in one of the lifetime management options.
So, you could say it's a bug, but I personally think it's just a case of a feature that is not needed for the intended use of the modules (this last phrase is just my personal opinion).
If you care to describe (maybe in another question?) what is the actual problem you're trying to solve with a disposable module, we can discuss that.

InstancePerLifeTimeScope and the life time of the objects

I am very new to Autofac dependency injection and I got these questions related to my project. I have gone through many articles but I am not getting a clear picture on some of the questions I have. Mine is a service application on .Net REST API. I am doing instance registration in App_Start module as shown below.
private static IContainer RegisterServices(ContainerBuilder builder)
{
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<DCLMessengerContext>()
.As<DbContext>()
.ExternallyOwned()
.InstancePerLifetimeScope();
builder.RegisterType<DbFactory>()
.As<IDbFactory>()
.ExternallyOwned()
.InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>()
.As<IUnitOfWork>()
.InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(EntityBaseRepository<>))
.As(typeof(IEntityBaseRepository<>))
.InstancePerLifetimeScope();
builder.RegisterType<PersonServiceClient>()
.As<IPerfService>()
.InstancePerLifetimeScope();
builder.RegisterType<PagingServiceContractClient>()
.As<PagingServiceContract>()
.InstancePerLifetimeScope();
builder.RegisterType<MessageService>()
.As<IMessageService>()
.InstancePerLifetimeScope();
Container = builder.Build();
return Container;
}
My service layer is "MessageService" and there I am performing all the DB and other integration operations and getting the instances through constructor injection. These are the questions I have around this implementation.
I am using InstancePerLifeTimeScope for all my registrations. Is this is the right approach? After the life cycle of each controller request (http request), will these instances will be automatically disposed?
Do we need to manually implement any Dispose operation on any of these instances? ( I don’t have any unmanaged objects in my code)
From the service method, I need to create a fire&forget thread as well using Task.Run(). What is the best approach to supply instances to this fire&forget thread? If I use InstancePerLifeTimeScope, I can see that new thread also getting the same instances that available through the service class so I am just confused when these instances will be disposed?
When you resolve the instance per lifetime scope component, you get a
single instance per nested scope
So if you are using them in controllers. You will have one object for per request and they will be disposed. But if you resolve them in a singleton object they wil live with this object.
Is this is the right approach?
It depends what you need. If you need singleton object, it's not. If you just want to use this service in request scope use instanceperrequest it's better.
Autofac automatically calls dispose for IDisposable objects. If you
need dispose method, implement it. It's not related with autofac.
If you use another thread resolve objects in this thread. Otherwise when request disposed your objects will be disposed and your thread will be fail. Check this.

Castle windsor instances are registered as singleton even though explicitly declare per web request

I am explicitly declaring my registerations as per web request lifecycle but they are still singletons.
this is a problem because my command handlers depend on an IDbConnection which is also registered per web request.
here is my registration code:
container.Register(
Classes
.FromAssemblyContaining<EcruiterCommands>()
.BasedOn(typeof (ICommandHandler<>))
.WithService.AllInterfaces()
.LifestylePerWebRequest());
I found the issue, the culprit is this line:
.BasedOn(typeof (ICommandHandler<>))
it resets the registration.

OSGi: What happens when an imported service is stopped while the service is still running

Say I am using a service A which is imported in another service B. While B is running normally(ofcourse A is Active), what will happen is service A is uninstalled while service B is still running?
Service A -> Service B
What will be the different scenarios in case I am using ServiceReference, ServiceTracker & DS?
When a service is unpublished in OSGi, an event is sent to all bundles currently using that service to tell them that they should stop using it.
If you are using DS, your unbind method will be called. When it is called, you should make best efforts to stop using the service as soon as possible. But ultimately OSGi is a cooperative system, it cannot force you to release the service. However if you don't then you can cause problems, for example the service publisher will not be fully garbage-collected. You end up sabotaging the dynamics of the OSGi platform, possibly creating memory leaks and so on.
If you are using ServiceTracker then the removedService method will be called, and you need to respond in the same way. But didn't I tell you in the other question not to use ServiceTracker?? ;-)
If you are using ServiceReference then you need to explicitly register a ServiceListener in order to receive these events. This is why you really really shouldn't use this low-level API until you have gained a lot more experience (and once you do have that experience, you won't want to use it anyway!).
First of all: one of the advantages of OSGi is that the behaviour of the framework and standard services are clearly specified. Those specifications can be downloaded from the OSGi Alliance web site, or, if you don't like reading PDFs, ordered for print. The question you are asking is perfectly answered in those specifications.
That said, in summary: when a service is unregistered:
The ServiceReference object remains as it is. However, a call to ServiceReference.getService() will return null. Note that when using ServiceReferences you should release any references to the actual service object as retrieved via getService(), this normally requires some kind of tracking of the service.
For ServiceTracker ServiceTracker.remove is called. This normally results in a call to removedService() on the ServiceTracker or the defined ServiceTrackerCustomizer.
For DS, the defined unbind method for the referenced service is called (if specified). Furthermore, if the cardinality for the used service indicates that the service is mandatory, the using service may also be unregistered, even possibly deactivated or a new instance activated depending on the availability of alternative services and the policy defined for the service.

Can components be temporarily registered in an Autofac container?

I'm building a plugin for a 3rd party application and my plugin uses Autofac to wire up various components. The container is built at application startup, but the host application invokes my commands at a later time.
When a command is invoked, the host application provides a few instances of types that it defines and that my components will need to use. I'd like to register these instances in the container so that it can take care of wiring up the components that depend on these instances.
I'm aware that I can use a ContainerBuilder to update an existing container, but I'd like to remove these registrations when the command has completed as these instances will no longer be valid. Is this possible?
Maybe a better approach is to use 2 containers... The command could create a new container to register these instances and other components could be resolved from the application scoped container.
How could I hook up the 2 containers so that resolve calls bubble up to the application scoped container?
Are there any gotchas to be aware of with this approach? I imagine there may be component lifetime issues...
Edit: Now I've done a bit more research and testing and and it turns out I can just use the BeginLifetimeScope(Action<ContainerBuilder>) overload to register the host application provided instances for the nested lifetime only. For some reason I thought that adding registrations to the nested lifetime would result in them being added to the root container but that doesn't seem to be the case.
As noted in my edit above, it turns out that BeginLifetimeScope(Action<ContainerBuilder>) is exactly what I need. For some reason I thought that adding registrations to the nested lifetime would result in them being added to the root container and therefore being resolvable after the nested lifetime scope ends, but that doesn't seem to be the case.