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

时间:2015-06-17 21:08:48

标签: c# dependency-injection mono decorator autofac

我有一个名为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(); 
}

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

为此,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   检测到循环组件依赖性:
  Services.AnonymousUserService - &gt;
  Services.AnonymousUserService - &gt;
  Services.AnonymousUserLastActivityUpdator - &gt;
Services.AnonymousUserLastActivityUpdator - &gt;
Services.AnonymousUserLastActivityUpdator。

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

1 个答案:

答案 0 :(得分:3)

您遇到此错误,因为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>();