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

这些方面的东西:

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

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

这不能直接使用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(); 

这不是很优雅,但它的工作原理。 现在,如果您可以详细说明为什么要这样做,也许有更好的方法。

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

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

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

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

会成为:

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

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