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