簡體   English   中英

如何使用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();

不幸的是,這不起作用。 無論是AnonymousUserServiceUserService得到的實例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種UserServiceAnonymousUserService注冊。

在第一個解決方案您注冊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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM