Autofac RegisterDecorator Error
I'm having some problems with the RegisterDecorator method in Autofac.
I currently have a nameless implementation of IUserManager, registered like so:
builder.RegisterType<UserManager>().As<IUserManager>().InstancePerLifetimeScope();
I am trying to add a nameless decorator to this implementation:
builder.RegisterDecorator<IUserManager>(inner => new UserManager2(inner), null);
However, I am receiving the following error:
The service IUserManager canno开发者_高级运维t be both the adapter's from and to parameters - these must differ.
Why must they differ? I thought the whole point of using decorators is so that you can transparently add zero-to-many decorators. Surely the implementation and the decorator must have the same interface AND keys to achieve this?
Autofac's RegisterDecorator
cannot be used as you would like. This is by design. As Nick says in a comment on your question.
Ordering of decorators usually turns out to be important enough that transparent schemes require augmentation with an order. Autofac just skips the transparency bit altogether (and it is a necessity of the implementation).
So, you have to to register the type to be decorated as a Named service using Named
in place of your As
and specify either a fromKey or toKey (of course you can specify both as well). The correct usage of RegisterDecorator is explained in this blog post.
The following code will work.
var cb = new ContainerBuilder();
cb.RegisterType<UserManager>().Named<IUserManager>("inner").InstancePerLifetimeScope();
cb.RegisterDecorator<IUserManager>((c, inner) => new UserManager2(inner), fromKey : "inner");
cb.Build();
You have also expressed in the comments below that this will not work in the case you have no decorators. I would suggest you use conditional registration in this case or a pass through decorator.
Update: Another update based on Nick's comment on the question. If you do not like either of these suggestions, an alternative to RegisterDecorator
is to use the Activating
event. As Nick writes:
The transparent decorators you're seeking can be implemented by hooking the Activating event and replacing e.Instance with the decorator as shown in this source code
精彩评论