C# 自动传真寄存器解码器错误

C# 自动传真寄存器解码器错误,c#,.net,dependency-injection,ioc-container,autofac,C#,.net,Dependency Injection,Ioc Container,Autofac,我对Autofac中的RegisterDecorator方法有一些问题 我目前有一个无名的IUserManager实现,注册方式如下: builder.RegisterType<UserManager>().As<IUserManager>().InstancePerLifetimeScope(); builder.RegisterType(); 我正在尝试向此实现添加一个无名的装饰器: builder.RegisterDecorator<IUserManage

我对Autofac中的RegisterDecorator方法有一些问题

我目前有一个无名的IUserManager实现,注册方式如下:

builder.RegisterType<UserManager>().As<IUserManager>().InstancePerLifetimeScope();
builder.RegisterType();
我正在尝试向此实现添加一个无名的装饰器:

builder.RegisterDecorator<IUserManager>(inner => new UserManager2(inner), null);
builder.RegisterDecorator(内部=>newusermanager2(内部),null);
但是,我收到以下错误:

服务IUserManager不能同时是适配器的from和to参数-它们必须不同


为什么它们必须有所不同?我认为使用decorator的全部意义在于,您可以透明地向许多decorator添加零。当然,实现和装饰器必须具有相同的接口和键才能实现这一点?

Autofac的
RegisterDecorator
不能按您的意愿使用。这是故意的。正如在对你的问题的评论中所说的

装饰师的排序通常非常重要,以至于 透明方案需要增加一个顺序。自动传真机 完全跳过透明度部分(这是 实施)

因此,您必须使用
Named
代替
as
将要修饰的类型注册为命名服务,并指定fromKey或toKey(当然您也可以同时指定两者)。中介绍了RegisterDecorator的正确用法

下面的代码将起作用

var cb = new ContainerBuilder();
cb.RegisterType<UserManager>().Named<IUserManager>("inner").InstancePerLifetimeScope();
cb.RegisterDecorator<IUserManager>((c, inner) => new UserManager2(inner), fromKey : "inner");
cb.Build();
var cb=newcontainerbuilder();
cb.RegisterType().Named(“内部”).InstancePerLifetimeScope();
cb.RegisterDecorator((c,inner)=>newusermanager2(inner),fromKey:“inner”);
cb.Build();
您也在下面的评论中表示,如果您没有装饰师,这将不起作用。我建议您在这种情况下使用有条件注册或通过装饰器

更新:根据对问题的评论进行的另一次更新。如果您不喜欢这两个建议中的任何一个,则可以使用
激活
事件来替代
RegisterDecorator
。尼克写道:

您正在寻找的透明装饰器可以通过 挂起激活事件并用 如中所示的装饰器


Autofac的
寄存器解码器
无法按您的意愿使用。这是故意的。正如在对你的问题的评论中所说的

装饰师的排序通常非常重要,以至于 透明方案需要增加一个顺序。自动传真机 完全跳过透明度部分(这是 实施)

因此,您必须使用
Named
代替
as
将要修饰的类型注册为命名服务,并指定fromKey或toKey(当然您也可以同时指定两者)。中介绍了RegisterDecorator的正确用法

下面的代码将起作用

var cb = new ContainerBuilder();
cb.RegisterType<UserManager>().Named<IUserManager>("inner").InstancePerLifetimeScope();
cb.RegisterDecorator<IUserManager>((c, inner) => new UserManager2(inner), fromKey : "inner");
cb.Build();
var cb=newcontainerbuilder();
cb.RegisterType().Named(“内部”).InstancePerLifetimeScope();
cb.RegisterDecorator((c,inner)=>newusermanager2(inner),fromKey:“inner”);
cb.Build();
您也在下面的评论中表示,如果您没有装饰师,这将不起作用。我建议您在这种情况下使用有条件注册或通过装饰器

更新:根据对问题的评论进行的另一次更新。如果您不喜欢这两个建议中的任何一个,则可以使用
激活
事件来替代
RegisterDecorator
。尼克写道:

您正在寻找的透明装饰器可以通过 挂起激活事件并用 如中所示的装饰器


Hi Lawrence,装饰器的排序通常非常重要,以至于透明方案需要增加一个顺序。Autofac完全跳过了透明度部分(这是实现的必要条件),干杯@尼古拉斯——当然,有时订货很重要。但我看不出这对我的问题有什么帮助。你是说RegisterDecorator方法是个坏主意,我不应该使用它吗?不,正如Ben指出的,实现装饰器的方法有很多种,选择的方法是最广泛适用的。您正在寻找的透明装饰器可以通过挂钩
激活
事件并用装饰器替换
e.Instance
来实现,如中所示。嗨,Lawrence,装饰器的顺序通常非常重要,以至于透明方案需要增加一个顺序。Autofac完全跳过了透明度部分(这是实现的必要条件),干杯@尼古拉斯——当然,有时订货很重要。但我看不出这对我的问题有什么帮助。你是说RegisterDecorator方法是个坏主意,我不应该使用它吗?不,正如Ben指出的,实现装饰器的方法有很多种,选择的方法是最广泛适用的。您正在寻找的透明装饰器可以通过挂钩
激活
事件并用装饰器替换
e.Instance
来实现,如中所示。但是为什么?如果没有装饰师呢?以不同的方式命名实现意味着在没有装饰器的情况下,它不会被注入到其他服务中。我的系统不应该依赖于至少有一个装饰师。我的系统是在多层体系结构上开发的,基本层提供工作服务,可以由更高级别的层进行修饰。对不起,但是-1.你不能在注册中加入一个条件吗?如果没有decorator,则不按命名注册,也不调用RegisterDecorator?另一个选项是始终注册一个传递decorator(只调用内部实现)。这并不漂亮,但这是一种选择。给我答案a-1的理由是什么?你没有提到“n”这个词