Autofac复合图案

时间:2011-02-23 15:01:27

标签: c# autofac

我注意到我经常需要实现复合模式。例如:

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

中的手工装饰

可以改进吗?

3 个答案:

答案 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>的分辨率解析合成。