views:

272

answers:

1

I am currently using Autofac, but am open to commentary regarding other IOC containers as well. I would prefer a solution using Autofac if possible. I am also somewhat new to IOC so I may be grossly misunderstanding what I should be using an IOC container for.

Basically, the situation is as follows:

I have a topmost IOC container for my app. I have a tree of child containers/scopes where I would like the same "service" (IWhatever) to resolve differently depending on which level in the tree it is resolved. Furthermore if a service is not registered at some level in the tree I would like the tree to be transversed upward until a suitable implementation is found.

Furthermore, when constructing a given component, it is quite possible that I will need access to the parent container/scope. In many cases the component that I'm registering will have a dependency on the same or a different service in a parent scope.

Is there any way to express this dependency with Autofac? Something like:

builder.Register(c=>
{
   var parentComponent = ?.Resolve<ISomeService>();
   var childComponent = new ConcreteService(parentComponent, args...);
   return childComponent;
}).As<ISomeService>();

I can't get anything similar to the above pseudocode to work for serveral reasons:

A) It seems that all levels in the scope tree share a common set of registrations. I can't seem to find a way to make a given registration confined a certain "scope".

B) I can't seem to find a way to get a hold of the parent scope of a given scope. I CAN resolve ILifetimeScope in the container and then case it to a concrete LifetimeScope instance which provides its parent scope, but I'm guessing it is probably note meant to be used this way. Is this safe?

C) I'm not sure how to tell Autofac which container owns the resolved object. For many components I would like component to be "owned" by the scope in which it is constructed. Could tagged contexts help me here? Would I have to tag every level of the tree with a unique tag? This would be difficult because the tree depth is determined at runtime.

Sorry for the extremely lengthy question. In summary:

1) Is there any way to do what I want to do using Autofac?

2) Is there another container more suited to this kind of dependency structure?

3) Is IOC the wrong tool for this altogether?

+2  A: 

Autofac 1.4 supports this easily and is probably the best choice here right now. You can simply register the child container components in the child container.

Autofac 2, which you're using, doesn't have a simple equivalent yet, although it is being investigated.

Nicholas Blumhardt
Excellent. Thanks for the help - sounds like I'll have to regress to 1.4 (for now). Just out of curiosity, why remove this behavior? Are the more common use-cases better supported by the AutoFac 2 lifetime scope model where the lifetime scopes share a common registration? Or is simply because autofac 2 is as of yet incomplete.Anyway - thank you very much for the help!
Krazzy
You're welcome. Autofac 2 should eventually support this, but the model is different so the implementation will take some thought. The change in the model makes it much easier to add 'adapters' for tasks like this that would otherwise require container manipulation. All the best!
Nicholas Blumhardt