Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PropertiesAutowired fails when service is decorated using new syntax #1041

Closed
tillig opened this issue Nov 1, 2019 · 2 comments · Fixed by #1043
Closed

PropertiesAutowired fails when service is decorated using new syntax #1041

tillig opened this issue Nov 1, 2019 · 2 comments · Fixed by #1043

Comments

@tillig
Copy link
Member

tillig commented Nov 1, 2019

Under Autofac 4.9.4 if you decorate a service that is marked PropertiesAutowired using the new decorator syntax, the property injection fails. Using the original decorator syntax property injection succeeds.

public interface IService
{
    bool NestedServiceIsNotNull();
}

public class Service : IService
{
    public NestedService NestedService { get; set; }

    public bool NestedServiceIsNotNull()
    {
        return NestedService != null;
    }
}

public class NestedService { }

public class ServiceDecorator : IService
{
    private readonly IService _original;

    public ServiceDecorator(IService original)
    {
        _original = original;
    }

    // The decorator doesn't have the property to inject,
    // only the service being decorated has it.
    public bool NestedServiceIsNotNull()
    {
        return _original.NestedServiceIsNotNull();
    }
}

public class UnitTest1
{
    [Fact]
    public void PropertyInjectionWithoutDecoratorWorks()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<NestedService>();
        builder.RegisterType<Service>().As<IService>().PropertiesAutowired();
        var container = builder.Build();
        var service = container.Resolve<IService>();

        Assert.True(service.NestedServiceIsNotNull());
    }

    [Fact]
    public void PropertyInjectionFailsWithNewDecoratorSyntax()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<NestedService>();
        builder.RegisterType<Service>().As<IService>().PropertiesAutowired();

        // Decorating the service with the new syntax causes the assertion to fail.
        builder.RegisterDecorator<ServiceDecorator, IService>();

        var container = builder.Build();
        var service = container.Resolve<IService>();

        Assert.True(service.NestedServiceIsNotNull());
    }

    [Fact]
    public void PropertyInjectionWorksWithOldSyntax()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<NestedService>();

        // Decorating the service with the old syntax works.
        builder.RegisterType<Service>().Named<IService>("service").PropertiesAutowired();
        builder.RegisterDecorator<IService>((c, inner) => new ServiceDecorator(inner), fromKey: "service");

        var container = builder.Build();
        var service = container.Resolve<IService>();

        Assert.True(service.NestedServiceIsNotNull());
    }
}
@RaymondHuy
Copy link
Member

Hi @tillig I think the reason is that the instance is decorated before the component raises activating event for its original instance. It happens also if we register with provided instance method. I have created a PR #1043 to fix it, Can you check about it ?

alexmg pushed a commit that referenced this issue Nov 3, 2019
…ng new syntax (#1043)

* Raise activating events for new instance before it is decorated
* Add test cases for issue#1041
* Remove unused property
@alexmg
Copy link
Member

alexmg commented Nov 3, 2019

Looks like that was indeed the issue. Your PR has been merged into develop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants