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

本文关键字:Autofac 何使用 注入 组件 循环 检测 依赖 DependencyResolutionException | 更新日期: 2023-09-27 17:56:45

我有一个名为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 装饰器部分获取的注册。

建筑工人。寄存器类型() .keyed(AuthenticatedStatus.Anonymous) .InstancePerRequest(); 建筑工人。寄存器类型() .键控(已验证状态。已验证) .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 检测到循环组件依赖关系:
服务.匿名用户服务 ->
服务.匿名用户服务 ->
Services.AnonymousUserLastActivityUpdator -> Services.AnonymousUserLastActivityUpdator ->

Services.AnonymousUserLastActivityUpdator.

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

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

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

如果你强制它:

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

您将有一个新的错误:

AnonymousUserLastActivityUpdator不包含接受 1 个参数的构造函数

此错误是由以下行引起的:

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>();