C# 如何使用Autofac在一个构造函数中注入类的装饰器,在另一个构造函数中注入类本身?

C# 如何使用Autofac在一个构造函数中注入类的装饰器,在另一个构造函数中注入类本身?,c#,dependency-injection,decorator,autofac,C#,Dependency Injection,Decorator,Autofac,我有一个IoCConfig,其中首先在RegisterDependencies方法中注册所有服务(与ServiceBase相同的程序集),除了一个名为lastActivityUpdater的服务和一个类以及该类的一个名为AnonymousUserLastActivityUpdater的装饰器之外,它们都实现了ILASTActivityUpdater 我想要实现的目标是让装饰师正确注册,这已经在下面工作了。我还要求一个类(UserService)使用LastActivityUpdater,另一个类

我有一个
IoCConfig
,其中首先在RegisterDependencies方法中注册所有
服务
(与
ServiceBase
相同的程序集),除了一个名为
lastActivityUpdater
的服务和一个类以及该类的一个名为
AnonymousUserLastActivityUpdater
的装饰器之外,它们都实现了
ILASTActivityUpdater

我想要实现的目标是让装饰师正确注册,这已经在下面工作了。我还要求一个类(
UserService
)使用
LastActivityUpdater
,另一个类(
AnonymousUserService
)使用
AnonymousUserLastActivityUpdater
)的方法,答案是。完整地说(我认为这与这个问题无关),我使用一个键控服务来决定在其他时间注入哪个类

不幸的是,当我结合这些想法时,我总是看到注入了
匿名用户LastActivityUpdater
,同样在
用户服务
的情况下,我希望提供一个
LastActivityUpdater

您可以在下面找到
IocConfig
,它使用idea注册装饰器并提供具有一种类型的特定类:

builder.RegisterAssemblyTypes(typeof(ServiceBase).Assembly)
    .Except<AnonymousUserService>()
    .Except<LastActivityUpdator>()
    .Except<AnonymousUserLastActivityUpdator>()
    .AsImplementedInterfaces()
    .InstancePerRequest();

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

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

builder.Register(c => new UserService(
    c.Resolve<OogstplannerUnitOfWork>(),
    c.Resolve<CookieProvider>(),
    c.Resolve<ILastActivityUpdator>()));
builder.Register(c => new AnonymousUserService(
    c.Resolve<OogstplannerUnitOfWork>(),
    c.Resolve<CookieProvider>(),
    c.Resolve<AnonymousUserLastActivityUpdator>()));

builder.RegisterType<AnonymousUserService>()
    .Keyed<IUserService>(AuthenticatedStatus.Anonymous)
    .InstancePerRequest();
builder.RegisterType<UserService>()
    .Keyed<IUserService>(AuthenticatedStatus.Authenticated)
    .InstancePerRequest();

您有两种注册方式,分别是
用户服务
匿名用户服务

在第一个解决方案中,通过显式调用构造函数并要求Autofac解析
AnonymousUserLastActivityUpdater
来注册
AnonymousUserService
,但没有注册此服务。您可以解析命名的
ILASTativityUpdater

builder.Register(c => new UserService(
    c.Resolve<OogstplannerUnitOfWork>(),
    c.Resolve<CookieProvider>(),
    c.Resolve<ILastActivityUpdator>()));
builder.Register(c => new AnonymousUserService(
    c.Resolve<OogstplannerUnitOfWork>(),
    c.Resolve<CookieProvider>(),
    c.ResolveNamed<ILastActivityUpdator>("anonymousUserLastActivityUpdator")));

您不必同时注册,最后一个就足够了。

嗨,西里尔,再次感谢您的回答。我们离得越来越近了:
UserService
注入了
lastActivityUpdater
,但一旦需要
AnonymousUserService
,就会弹出检测到的错误
循环组件依赖关系。我确实对你提供的答案做了一些调整,所以我可能在这里犯了一个错误。我已经更新了答案(在/edit下),如果您能看一看,我将非常高兴您不应该使用
WithParameter
方法进行注册。这样做,您的注册没有使用装饰器。对于此错误,是否需要使用
RegisterAssemblyTypes
方法注册类型?我建议您手动注册所有类型,不要使用程序集扫描之类的方法。它会让你完全控制你的注册。尝试手动注册您的类型,错误消息可能会更明确谢谢!我成功了!工作注册按如下方式注册
UserService
builder.Register(c=>newuserservice(c.Resolve(),c.Resolve(),c.ResolveNamed(“LastActivityUpdater”)).as().InstancePerRequest()。问题是,我认为,解析
ILASTativityUpdater
会自动生成一个
AnonymousUserLastActivityUpdater
,这在ResolveNamed方法中不会发生。再次感谢您的帮助!另外,
(p,c)=>p.Name==“updater”
部分不能是
(p,c)=>p.Name==“AnonymousUserLastActivityUpdater”
,因为当使用与命名注册相同的名称时,会给您一个
DependencyResolutionException
builder.Register(c => new UserService(
    c.Resolve<OogstplannerUnitOfWork>(),
    c.Resolve<CookieProvider>(),
    c.Resolve<ILastActivityUpdator>()));
builder.Register(c => new AnonymousUserService(
    c.Resolve<OogstplannerUnitOfWork>(),
    c.Resolve<CookieProvider>(),
    c.ResolveNamed<ILastActivityUpdator>("anonymousUserLastActivityUpdator")));
builder.RegisterType<AnonymousUserService>()
       .Keyed<IUserService>(AuthenticatedStatus.Authenticated)
       .InstancePerRequest();
builder.RegisterType<UserService>()
       .Keyed<IUserService>(AuthenticatedStatus.Anonymous)
       .WithParameter(
         (pi, c) => pi.Name == "updater", 
         (pi, c) => ResolveNamed<ILastActivityUpdator>("anonymousUserLastActivityUpdator"))
       .InstancePerRequest();