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.
You register components with Autofac by creating a ContainerBuilder and informing the builder which components expose which services. Components can be created via reflection (by registering a specific .
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With