如何在autofac中的RegistrationSource之后设置ComponentRegistration

时间:2015-05-26 07:07:01

标签: c# autofac

示例代码:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterSource(new RegistrationSource());
builder.RegisterType<Cmd1>().AsSelf().As<ICmd>();
IContainer container = builder.Build();
var cmds = container.Resolve<IEnumerable<ICmd>>();

RegistrationSource将提供Cmd2类型,cmds结果为cmd1cmd2。但我想要Cmd2Cmd1

我该怎么做?

1 个答案:

答案 0 :(得分:0)

  

如果RegistrationSource无法恢复组件,它将返回由RegisterType或其他解决方案提供的默认组件

RegistrationSource不会返回任何内容。它只向组件注册表注册新注册。

我认为你想要的是当 Autofac 解决问题时,它会首先尝试使用RegistrationSource提供的注册,如果没有,它应该尝试使用没有RegistrationSource的注册。是对的吗 ?

这是不可能的。无论是否由RegistrationSource提供,所有注册都是等效的。

但是,您可以注册许多名为IFoo且只有一个IFoo来选择要使用的正确名称IFoo,而不是注册多个IFoo

builder.Register(c => c.ResolveNamed<IEnumerable<Meta<IFoo>>>("Ordered")
                       .OrderBy(metaFoo => (Int32)metaFoo.Metadata["order"])
                       .Select(metaFoo => metaFoo.Value)
                       .First())
       .As<IFoo>();

// classic registration
builder.RegisterType<Foo1>()
       .Named<IFoo>("Ordered")
       .WithMetadata("order", 20);


// this registration can be provided by a RegistrationSource
builder.RegisterType<Foo2>()
       .Named<IFoo>("Ordered")
       .WithMetadata("order", 10);

现在 Autofac 会在结算order

时检查名为IFoo注册的IFoo元数据

在澄清之前做出了以下回答

您可以使用PreserveExistingDefaults方法将注册推送到注册列表的末尾。

builder.RegisterType<Foo1>().As<IFoo>();
builder.RegisterType<Foo2>().As<IFoo>().PreserveExistingDefaults();

// ...

container.Resolve<IEnumerable<IFoo>>() => Foo1, Foo2

在您的情况下,如果您想控制注册的顺序,我建议您使用meta进行操作。

builder.RegisterType<Foo1>().As<IFoo>().WithMetadata("order", 10);
builder.RegisterType<Foo2>().As<IFoo>().WithMetadata("order", 20);
builder.RegisterType<Foo3>().As<IFoo>().WithMetadata("order", 15);
// ...

IEnumerable<IFoo> foos = container.Resolve<IEnumerable<Meta<IFoo>>>()
                                    .OrderBy(o => (Int32)o.Metadata["order"])
                                    .Select(o => o.Value);

// foos => Foo1, Foo3, Foo2

如果您想更进一步,可以实施一个自定义IRegistrationSource,为IOrderedEnumerable<T>提供注册。每次您需要有序的可枚举时,您将能够解决IOrderedEnumerable<T>并确保订单。