Is it possible to remove an existing registration from Autofac container builder?

懵懂的女人 提交于 2019-11-30 22:29:56

问题


Something along those lines:

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));

Scenario: I go through bunch of assemblies and as I go I register types but I want to make sure that I have only one implementation of a given type. I need to do this before I create the container. I could track that on my own but it would be nice if Autofac could help me a bit.


回答1:


This cannot be done directly using the ContainerBuilder, unless you start over with a new one. Mind you, having first built a container you should be able to construct a new container filtering away unwanted types and reusing the registrations from the first container. Like this:

...
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();

This is hardly very elegant but it works. Now, if you could elaborate on why you want to do this, perhaps there is a better way.




回答2:


Peter L.'s probably got the most straightforward option.

To get around the problem altogether, can you modify the way you're discovering components to filter them in advance of registration? It does seem like there must be an approach that gets around this... It also might be a challenge further down the track to work out which components to keep vs. which to remove.

A more involved approach is to override IEnumerable support to filter out the the things you don't want. I.e. copy and modify this code to create a FilteredCollectionSource that excludes the components you don't want.

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

would become:

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

If you add your FilteredCollectionSource to the builder using RegisterSource() it will should get used instead of the built-in one.



来源:https://stackoverflow.com/questions/5091101/is-it-possible-to-remove-an-existing-registration-from-autofac-container-builder

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!