开发者

Autofac composite pattern

开发者 https://www.devze.com 2023-02-13 03:18 出处:网络
I noticed I quite often need to implement composite pattern. For example: interface IService { ... } class Service1 : IService { ... }

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<IS开发者_Python百科ervice>>("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

  • inject all other implementations of the interface into the composite
  • register the composite as the default interface implementation
  • not resolve the composite in IEnumerable<Interface> resolutions.
0

精彩评论

暂无评论...
验证码 换一张
取 消