DependencyResolutionException 检测到循环组件依赖:如何使用 Autofac 注入装饰器?

DependencyResolutionException Circular component dependency detected: How to use Autofac to inject decorator?

我有一个名为 ILastActivityUpdator 的接口,如下所示:

public interface ILastActivityUpdator
{
    void UpdateLastActivity(int userId);
}

除此之外,我有两个 类 实现了这个接口,LastActivityUpdator 和一个装饰器 AnonymousUserLastActivityUpdator。后者将 ICookieProvider 作为额外参数并在方法实现中使用它。即,

public LastActivityUpdator(IUnitOfWork unitOfWork) 
    : base(unitOfWork)
{ }

public void UpdateLastActivity(int userId)
{
    // Do some stuff.
}

装饰器:

public AnonymousUserLastActivityUpdator(
    IUnitOfWork unitOfWork,
    ICookieProvider cookieProvider,
    ILastActivityUpdator lastActivityUpdator) 
    : base(unitOfWork)
{
    this.lastActivityUpdator = lastActivityUpdator;
    this.cookieProvider = cookieProvider;
}

public void UpdateLastActivity(int userId)
{
    lastActivityUpdator.UpdateLastActivity(userId);

    cookieProvider.SetCookie(); 
}

我想在 AnonymousUserService 中注入 AnonymousUserLastActivityUpdator,在 UserService 中注入 LastActivityUpdator

为此,我在 IoCConfig 中的 RegisterDependencies 方法包含从 Autofac FAQ Decorator section.

中获取的以下注册

builder.RegisterType() .Keyed(AuthenticatedStatus.Anonymous) .InstancePerRequest(); builder.RegisterType() .Keyed(AuthenticatedStatus.Authenticated) .InstancePerRequest();

builder.RegisterType<LastActivityUpdator>()
    .Named<ILastActivityUpdator>("lastActivityUpdator");
builder.RegisterType<AnonymousUserLastActivityUpdator>()
    .Named<ILastActivityUpdator>("lastActivityUpdator");

// Then register the decorator. The decorator uses the
// named registrations to get the items to wrap.
builder.RegisterDecorator<ILastActivityUpdator>(
    (c, p, inner) => new AnonymousUserLastActivityUpdator(
        c.Resolve<IOogstplannerUnitOfWork>(), 
        c.Resolve<ICookieProvider>(),
        inner),
    fromKey: "lastActivityUpdator");

不幸的是,当我 运行 代码时出现错误:

Autofac.Core.DependencyResolutionException Circular component dependency detected:
Services.AnonymousUserService ->
Services.AnonymousUserService ->
Services.AnonymousUserLastActivityUpdator ->
Services.AnonymousUserLastActivityUpdator ->
Services.AnonymousUserLastActivityUpdator.

此外,我不明白为什么会神奇地注入正确的实现。有谁知道如何解决这个问题?

出现此错误是因为 C# 编译器不知道要采用 RegisterDecorator 方法的哪个重载。

如果你强迫它:

builder.RegisterDecorator<ILastActivityUpdator>(
    new Func<IComponentContext, ILastActivityUpdator, ILastActivityUpdator>(
        (c, inner) => new AnonymousUserLastActivityUpdator(inner)
    ),
    fromKey: "lastActivityUpdator");

您将遇到一个新错误:

AnonymousUserLastActivityUpdator does not contain a constructor that takes 1 arguments

这个错误是由这一行引起的:

new AnonymousUserLastActivityUpdator(inner)

要解决此错误,您必须更改创建 AnonymousUserLastActivityUpdator

实例的方式

例如:

// only the type being decorated should be registered here
builder.RegisterType<LastActivityUpdator>()
       .Named<ILastActivityUpdator>("lastActivityUpdator");

builder.RegisterDecorator<ILastActivityUpdator>(
    (c, inner) => new AnonymousUserLastActivityUpdator(c.Resolve<IUnitOfWork>(), 
                                                       c.Resolve<ICookieProvider>(), 
                                                       inner),
    fromKey: "lastActivityUpdator")
       .As<ILastActivityUpdator>(); 

甚至更好:

builder.RegisterType<LastActivityUpdator>()
       .Named<ILastActivityUpdator>("lastActivityUpdator");
builder.RegisterType<AnonymousUserLastActivityUpdator>()
       .Named<ILastActivityUpdator>("anonymousLastActivityUpdator");

builder.RegisterDecorator<ILastActivityUpdator>(
    (c, inner) => c.ResolveNamed<ILastActivyUpdator>("anonymousLastActivityUpdator", 
                                                     TypedParameter.From(inner)),
    fromKey: "lastActivityUpdator")
       .As<ILastActivityUpdator>();