我注意到我经常需要实现复合模式。例如:
interface IService { ... }
class Service1 : IService { ... }
class Service2 : IService { ... }
class CompositeService : IService
{
public CompositeService(IEnumerable<IService> services) { ... }
...
}
我想在容器中将CompositeService注册为IService并注入依赖项。
(看起来有点类似于Decorator但是装饰一组服务而不是一个)
在autofac中执行此操作的最佳方式是什么?
理想的解决方案如何(对于C#)?
更新
我目前的注册是:
builder.RegisterType<Service1>().Named<IService>("impl");
builder.RegisterType<Service2>().Named<IService>("impl");
builder.Register(c => new CompositeService(c.Resolve<IEnumerable<IService>>("impl")))
.As<IService>();
类似于http://nblumhardt.com/2011/01/decorator-support-in-autofac-2-4
中的手工装饰可以改进吗?
答案 0 :(得分:3)
我没有实现这一点,甚至没有完全考虑过,但我能达到的最佳语法是:
builder
.RegisterComposite<IService>((c, elements) => new CompositeService(elements))
.WithElementsNamed("impl");
注册函数的elements
参数的类型为IEnumerable<IService>
,并封装c.Resolve<IEnumerable<IService>>("impl")
。
现在该怎么写呢......
答案 1 :(得分:1)
您可以尝试命名或键控注册。命名注册只是获取一个字符串名称,以区别于同一接口的其他注册。类似地,密钥使用某种值类型(例如枚举)来区分多个注册。您的CompositeService可能是默认引用,按类型注册,不需要其他特殊信息。您需要一些方法来解析其他IService依赖项并将它们传递给构造函数; CompositeService的工厂方法可以工作。
答案 2 :(得分:1)
综合注册will be coming in AutoFac 6.0。
它不会自动为您创建合成,但会
IEnumerable<Interface>
的分辨率解析合成。