I noticed I quite often need to implement composite pattern. For example:
interface IService { ... }
class Service1 : IService { ... }
class Service2 : IService { ... }
class CompositeService : IService
{
public CompositeService(IEnumerable<IService> services) { ... }
...
}
I want to register CompositeService as IService in container and have dependencies injected.
(looks somewhat similar to Decorator but decorating set of services instead of only one)
What's the best way to do it in autofac?
How would ideal solution look like (for C#)?
Update:
My current registration is:
builder.RegisterType<Service1>().Named<IService>("impl");
builder.RegisterType<Service2>().Named<IService>("impl");
builder.Register(c => new CompositeService(c.Resolve<IEnumerable<IService>>("impl")))
.As<IService>();
It is similar to Decorators by Hand in http://nblumhardt.com/2011/01/decorator-support-in-autofac-2-4
Can it be improved?
I haven't implemented this or even thought it through fully, but the best syntax I could achieve is:
builder
.RegisterComposite<IService>((c, elements) => new CompositeService(elements))
.WithElementsNamed("impl");
The elements
parameter to the registration function would be of type IEnumerable<IService>
and encapsulate the c.Resolve<IEnumerable<IService>>("impl")
.
Now how to write it...
You could try named or keyed registrations. A named registration simply gets a string name, to differentiate it from other registrations of the same interface. Similarly, a key uses some value type, for instance an enum, to discriminate between multiple registrations. Your CompositeService would likely be the default reference, registered by type with no other special info needed. You'll need some method to resolve the other IService dependencies and pass them to the constructor; a factory method for CompositeService may work.
Composite registration will be coming in AutoFac 6.0.
It won't automatically create a composite for you, but it will
IEnumerable<Interface>
resolutions.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With