I am migrating an existing service to be multi-tennated, and in the process will need to rewire all my dependencies, and mange their reuse scope to be Request.
I have already migrated our Azure workerroles which runs 7 worker processes in parallel, by registering all the ‘global’ singleton components in the main container, and creating 7 child containers and registering the tenant-sensitive singletons in each child container. So that each worker has its own copies of the components it needs without interfering with other worker dependencies. So have some experience using child containers for that. But this does not use the scope Request of course.
Now, I want to migrate my webrole, which currently has everything as singletons in the main container.
I am thinking, for the web service, that I will put all the global components as singletons in the main container (as they are today), but put all the tenancy-sensitive components in new child container that has DefaultReuse = ReuseScope.Request, rather then just adding .ReuseWithin(ReuseScope.Request) on every one of them (there are about 100 of them).
If I was to do that though, I am not sure how GlobalFilters, RequestFilters and other extensions that make calls like IRequest.TryResolve<T> are going to resolve if the components are in a child container, rather that in the main container, so might be adding more complexity than necessary.
Is using a child container like this a feasible pattern, or should I revert back to just adding .ReuseWithin(ReuseScope.Request) to my components? Or is there another option?
Personally I only ever use Singleton or Transient dependencies. If the dependency is Thread Safe it’s registered as a singleton otherwise it’s registered as a transient dependency.
IRequest.TryResolve<T> essentially ends up delegating to resolving from the AppHost’s Container. Use RequestScope if you need to, another option is to add any dependencies you need down the request pipeline to IRequest.Items. ServiceStack automatically disposes any IDisposable registered in IRequest.Items at the end of the request. My preference is to only attach state to the request and have anything that requires dependencies retrieve it from the IOC as needed.
I wouldn’t use child containers, I don’t know of any reason to or know of anyone who does.
Don’t use: .ReuseWithin(ReuseScope.Request), but use: .ReuseWithin(ReuseScope.None)
Stuff request dependencies into IRequest.Items as an alternative approach.
Don’t use child containers for this purpose.
thanks
p.s. our use of child containers is very useful in fact in our worker scenario, but granted, in that scenario, there is no AppHost nor service its just Funq.
But how do you handle IDbConnection dependencies within the same request? Singleton is no option and transient means a lot of opening/closing the connection…
It’s more efficient to release DB Connections back to the pool (the default for most ADO.NET providers) immediately after its no longer used then it is to retain and block its reuse for the entire Request.