使用接口继承时如何防止 Autofac 中嵌套装饰器?

sno*_*dev 5 .net c# dependency-injection decorator autofac

我有一个 .NET 7.0 应用程序,其中使用 Autofac 作为我的 DI 容器。我有两个接口IReadonlyRepository<T>IRepository<T>,其中IRepository<T>继承自IReadonlyRepository<T>.

我的存储库类实现了这些接口。我还有一个装饰器 ,LoggingRepository<T>它包装IRepository<T>、记录对存储库方法的每个调用,并将调用委托给包装的IRepository<T>实例。这是代码LoggingRepository<T>

class LoggingRepository<T> : IRepository<T>
{
    private readonly IRepository<T> _repository;

    public LoggingRepository(IRepository<T> repository)
    {
        _repository = repository;
    }

    public IEnumerable<T> List()
    {
        Console.WriteLine($"Calling {_repository.GetType().Name}<{typeof(T).Name}>.List()");
        return _repository.List();
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是我在 DI 容器中注册类和装饰器的方法:

builder.RegisterGeneric(typeof(Repository<>))
    .As(typeof(IRepository<>))
    .As(typeof(IReadonlyRepository<>))
    .InstancePerLifetimeScope();

builder.RegisterGenericDecorator(typeof(LoggingRepository<>), typeof(IRepository<>));
builder.RegisterGenericDecorator(typeof(LoggingRepository<>), typeof(IReadonlyRepository<>));
Run Code Online (Sandbox Code Playgroud)

我还尝试使用命名注册来潜在地规避此问题,但它并没有改变行为。

我面临的问题是,当我请求 的实例时IReadonlyRepository<T>,似乎LoggingRepository<T>最终装饰了另一个实例LoggingRepository<T>,而该实例又装饰了该Repository<T>实例。这不是预期的行为 - 我只想LoggingRepository<T>装饰的单个实例Repository<T>

实际上,系统似乎是嵌套装饰器,因为 IRepository 也实现了 IReadonlyRepository。

在这种情况下如何防止 Autofac 嵌套装饰器?在处理接口继承时注册这些装饰器以确保它们不嵌套的正确方法是什么?