autofac/Autofac

Decorators does not follow ExternallyOwned - problem with lifetime scope on decorator with `IDisposable` implementation

Fechada

#1.402 aberto em 9 de nov. de 2023

 (0 comentário) (1 reação) (0 responsável)C# (827 forks)batch import
enhancementhelp wanted

Métricas do repositório

Stars
 (4.327 estrelas)
Métricas de merge de PR
 (Mesclagem média 3h 24m) (10 fundiu PRs em 30d)

Description

Describe the Bug

According to documentation: You cannot specify a lifetime scope on a decorator. The lifetime of a decorator is tied to the lifetime of the thing it decorates. but it is not working when thing it decorates implements IDisposable

Steps to Reproduce

using Autofac;

Console.WriteLine("Hello, World!");

var builder = new ContainerBuilder();

builder.RegisterType<Parser>().As<IParser>().ExternallyOwned().InstancePerLifetimeScope();
builder.RegisterDecorator<ParserDecorator, IParser>(); // according to docs cant be marked as ExternallyOwned but has same lifetime as IParser

using var container = builder.Build(); // <== using --> Dispose() is called on ParserDecorator decorator even if IParser is ExternallyOwned
using var parser = container.Resolve<IParser>(); // <== using --> Dispose() is called on IParser
parser.Parse();

// Output (please notice Dispose() called twice):
/* 
Hello, World!
Before Parse
Parsing...
Parsed
After Parse
Disposed ParserDecorator
Disposed Parser
Disposed ParserDecorator
Disposed Parser
*/

public interface IParser : IDisposable
{
    void Parse();
}

public class Parser : IParser
{
    public void Parse()
    {
        Console.WriteLine("Parsing...");
        Console.WriteLine("Parsed");
    }

    public void Dispose()
    {
        Console.WriteLine("Disposed Parser");
    }
}

public class ParserDecorator : IParser
{
    private readonly IParser _parser;

    public ParserDecorator(IParser parser)
    {
        _parser = parser;
    }

    public void Parse()
    {
        Console.WriteLine("Before Parse");
        _parser.Parse();
        Console.WriteLine("After Parse");
    }

    public void Dispose()
    {
        Console.WriteLine("Disposed ParserDecorator");
        _parser.Dispose();
    }
}

Expected Behavior

Decorators follows "externally owned" state on "thing" it decorates.

Dependency Versions

Autofac: 7.1.0

Tags

autofac decorator externally owned idisposable

Guia do colaborador