![](/img/trans.png)
[英]How to inject service to class with parameters in constructor using autofac?
[英]How to use Autofac to inject decorator of a class in one constructor and the class itself in another?
我有一個IoCConfig
,其中首先在RegisterDependencies方法中注冊所有Services
(與ServiceBase
相同的程序集),除了一個服務和一個名為LastActivityUpdator
類以及該類的名為AnonymousUserLastActivityUpdator
的裝飾器,它們均實現ILastActivityUpdator
。
我要實現的目標是正確地裝飾裝飾器,該裝飾器已經可以按照此答案進行操作 。 我也問了路,為一類( UserService
)使用LastActivityUpdator
和另一個( AnonymousUserService
)使用AnonymousUserLastActivityUpdator
,這是回答了這里 。 為了完整起見(我認為這與該問題無關),我將在此答案之后使用鍵控服務來確定在其他時間注入了哪個類。
不幸的是,當我結合這些想法時,我總是看到注入了AnonymousUserLastActivityUpdator
,在UserService
的情況下,我也希望提供LastActivityUpdator
。
在您的下方''找到了IocConfig
,它使用了這種思想來注冊裝飾器並提供一種類型的特定類:
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();
不幸的是,這不起作用。 無論是AnonymousUserService
和UserService
得到的實例LastActivityUpdator
,而我想AnonymousUserService
獲得的實例AnonymousUserService
。
有誰知道為什么我的RegisterDependencies方法不向UserService
提供LastActivityUpdator
以及我如何才能做到這一點?
/編輯
使用Cyril的答案和一些調整,可以為UserService
注冊,但是一旦用戶注銷並使用AnonymousUserService
,我就會收到錯誤消息:
檢測到循環組件依賴性:
Services.AnonymousUserService->
Services.AnonymousUserService->
Services.AnonymousUserLastActivityUpdator->
Services.AnonymousUserLastActivityUpdator-> System.Object->
Services.AnonymousUserLastActivityUpdator
我調整了Cyril的答案的代碼(修正了一些輸入錯誤,並切換了匿名用戶服務和普通用戶服務),我可能會犯一個錯誤,這里是:
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.RegisterType<UserService>()
.Keyed<IUserService>(AuthenticatedStatus.Authenticated)
.WithParameter(
(p, c) => p.Name == "lastActivityUpdator",
(p, c) => c.ResolveNamed<ILastActivityUpdator>("lastActivityUpdator"))
.InstancePerRequest();
builder.RegisterType<AnonymousUserService>()
.Keyed<IUserService>(AuthenticatedStatus.Anonymous)
.WithParameter(
(p, c) => p.Name == "anonymousUserLastActivityUpdator",
(p, c) => c.ResolveNamed<ILastActivityUpdator>("anonymousUserLastActivityUpdator"))
.InstancePerRequest();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
您有2種UserService
和AnonymousUserService
注冊。
在第一個解決方案您注冊AnonymousUserService
通過顯式調用構造函數,並通過詢問Autofac解析AnonymousUserLastActivityUpdator
但該服務沒有注冊。 除了解決這種類型,您還可以解決一個名為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.ResolveNamed<ILastActivityUpdator>("anonymousUserLastActivityUpdator")));
第二個注冊是一個Keyed
但你不指定該AnonymousUserService
應該使用anonymousUserLastActivityUpdater
使用,你可以做到這一點WithParameter
方法
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();
您不必同時注冊,最后一個注冊對於您的情況就足夠了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.