-
-
Notifications
You must be signed in to change notification settings - Fork 846
Closed
Labels
Description
Reproduced in Autofac trunk DecoratorTests, but also noted in Autofac 5.1.2.
If one or more services (e.g. IService) are registered with a specific lifetime (InstancePerLifetimeScope, SingleInstance), resolving IEnumerable will return instances of all of the types as normal, but adding a decorator into the mix breaks the IEnumerable resolution, replacing all instances with the first "reusable" instance. Similarly, once IEnumerable is resolved, trying to resolve IService no longer returns the last registration, but instead also returns the "reusable" decorated instance noted in the IEnumerable case
[Fact]
public void CanResolveMultipleDecoratedServicesSingleInstance()
{
var builder = new ContainerBuilder();
builder.RegisterType<ImplementorA>().As<IDecoratedService>();
builder.RegisterType<ImplementorB>().As<IDecoratedService>().SingleInstance();
builder.RegisterDecorator<DecoratorA, IDecoratedService>();
var container = builder.Build();
var services = container.Resolve<IEnumerable<IDecoratedService>>();
Assert.Collection(
services,
s =>
{
Assert.IsType<DecoratorA>(s);
Assert.IsType<ImplementorA>(s.Decorated);
},
s =>
{
Assert.IsType<DecoratorA>(s);
Assert.IsType<ImplementorB>(s.Decorated);
});
services = container.Resolve<IEnumerable<IDecoratedService>>();
Assert.Collection(
services,
s =>
{
Assert.IsType<DecoratorA>(s);
//Fails because s.Decorated is of type ImplementorB
Assert.IsType<ImplementorA>(s.Decorated);
},
s =>
{
Assert.IsType<DecoratorA>(s);
Assert.IsType<ImplementorB>(s.Decorated);
});
}
[Fact]
public void CanResolveSingleServiceAfterMultipleDecoratedServicesSingleInstance()
{
var builder = new ContainerBuilder();
builder.RegisterType<ImplementorA>().As<IDecoratedService>().SingleInstance();
builder.RegisterType<ImplementorB>().As<IDecoratedService>();
builder.RegisterDecorator<DecoratorA, IDecoratedService>();
var container = builder.Build();
container.Resolve<IEnumerable<IDecoratedService>>();
var service = container.Resolve<IDecoratedService>();
Assert.IsType<DecoratorA>(service);
//Fails because s.Decorated is of type ImplementorA
Assert.IsType<ImplementorB>(service.Decorated);
}
Reactions are currently unavailable