是否可以从Autofac容器构建器中删除现有注册?

时间:2011-02-23 12:46:43

标签: c# autofac

沿着这些方向:

builder.RegisterType<MyType>().As<IType>();
builder.RegisterType<MyType2>().As<IType>();
builder.DeRegisterType<MyType>().As<IType>()

var container = builder.Build();
var types = container.Resolve<IEnumerable<IType>>();
Assert.IsTrue(types.Count == 1);
Assert.IsTrue(types[0].GetType == typeof(MyType2));

场景:我经历了一堆程序集,然后我去注册类型,但我想 确保我只有一个给定类型的实现。我需要在创建容器之前执行此操作。我可以自己跟踪,但如果Autofac可以帮助我,那将会很好。

2 个答案:

答案 0 :(得分:12)

除非您重新开始使用ContainerBuilder,否则无法直接使用... var container = builder.Build(); builder = new ContainerBuilder(); var components = container.ComponentRegistry.Registrations .Where(cr => cr.Activator.LimitType != typeof(LifetimeScope)) .Where(cr => cr.Activator.LimitType != typeof(MyType)); foreach (var c in components) { builder.RegisterComponent(c); } foreach (var source in container.ComponentRegistry.Sources) { cb.RegisterSource(source); } container = builder.Build(); 。请注意,首先构建一个容器,您应该能够构建一个新容器,过滤掉不需要的类型并重用第一个容器中的注册。像这样:

{{1}}

这不是很优雅,但它有效。现在,如果你能详细说明为什么你想要这样做,也许还有更好的方法。

答案 1 :(得分:1)

Peter L.可能是最直接的选择。

要彻底解决问题,您是否可以修改发现组件的方式,以便在注册之前对其进行过滤?似乎必须有一种方法可以解决这个问题......这也可能是一个挑战,以确定哪些组件要保留哪些组件以及要删除哪些组件。

更复杂的方法是覆盖IEnumerable支持,以过滤掉您不想要的内容。即复制并修改此代码以创建排除您不想要的组件的FilteredCollectionSource

var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService);

会变成:

var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService)
    .Where(reg => /* not a duplicate */);

如果您使用FilteredCollectionSourceRegisterSource()添加到构建器,则应该使用它而不是内置的构建器。