C# Autofac复合图案

C# Autofac复合图案,c#,autofac,C#,Autofac,我注意到我经常需要实现复合模式。例如: interface IService { ... } class Service1 : IService { ... } class Service2 : IService { ... } class CompositeService : IService { public CompositeService(IEnumerable<IService> services) { ... } ... } 接口IService{…}

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

interface IService { ... }
class Service1 : IService { ... }
class Service2 : IService { ... }
class CompositeService : IService
{
    public CompositeService(IEnumerable<IService> services) { ... }
    ...
}
接口IService{…}
类服务1:IService{…}
类服务2:IService{…}
类复合服务:IService
{
公共复合服务(IEnumerable服务){…}
...
}
我想在容器中将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>();
builder.RegisterType().Named(“impl”);
builder.RegisterType()。命名为(“impl”);
builder.Register(c=>newcompositeservice(c.Resolve(“impl”))
.As();
它类似于手工装饰


可以改进吗?

您可以尝试命名或键入注册。命名注册仅获取字符串名称,以将其与同一接口的其他注册区分开来。类似地,键使用某种值类型(例如枚举)来区分多个注册。您的CompositeService可能是默认引用,按类型注册,不需要其他特殊信息。您需要一些方法来解析其他iSeries设备依赖项并将它们传递给构造函数;CompositeService的工厂方法可能会起作用。

我还没有实现这一点,甚至没有仔细考虑,但我能实现的最佳语法是:

builder
.RegisterComposite<IService>((c, elements) => new CompositeService(elements))
.WithElementsNamed("impl");
builder
.RegisterComposite((c,元素)=>新的CompositeService(元素))
.不包含任何元素(“impl”);
注册函数的
元素
参数的类型应为
IEnumerable
,并封装
c.Resolve(“impl”)

现在如何编写它…

复合注册

它不会自动为您创建合成,但会

  • 将接口的所有其他实现注入到组合中
  • 将组合注册为默认接口实现
  • IEnumerable
    分辨率中不解析组合

谢谢!我现在正在做你描述的事情。我希望有一个更智能、更短的代码。对于简单的情况,我也会提出一个更简单的版本:
builder.RegisterCompositeType(“impl”)
。我只是不喜欢手动调用构造函数,因为依赖项已经可以被注入了。@Konstantin Spirin:我曾考虑过加入那个重载,但想在我的答案中明确说明发生了什么。我唯一要改变的是,我仍然使用
WithElementsNamed
(以及
WithElementsKeyed
)方法,这样我们就不必为各种注册类型创建
RegisterComposite
的重载(这是其他注册方法对命名/键控类型所做的)。