I want to decorate IService
in such a way that some consumers will a specific decorator based on their type, something like this:
container.Register<IService, Service>();
container.RegisterDecorator<IService, ServiceWithCaching>();
container.RegisterDecoratorConditional<IService, ServiceWithLogging>
(ctx => ctx.Consumer.ServiceType ==
typeof(IConsumerThatNeedsDecoratedService));
container.Register<IConsumerThatNeedsServiceWithLogging, Consumer1>();
container.Register<INormalConsumer, Consumer2>();
where both ServiceWithCaching
and ServiceWithLogging
take IService
in their constructor, wrap an instance of IService, call it internally and do something else (e.g. caching, logging).
Both Consumer1
and Consumer2
accept IService
in their constructor.
I want Consumer1
to be injected an instance of ServiceWithLogging
and Consumer2
of ServiceWithCaching
. The desired behvavior is that Consumer1
will use an instance of IService
that caches the results, while Consumer2
will use an instance of IService
that both caches results an logs calls.
Is it possible in Simple Injector and if not any known workarounds?
You can't do this with RegisterDecorator
, but as the Applying decorators conditionally based on consumer section of the documentation explains, you can achieve this using RegisterConditional
:
container.RegisterConditional<IService, ServiceWithLogging>(
c => c.Consumer.ImplementationType == typeof(Consumer1));
container.RegisterConditional<IService, ServiceWithCaching>(
c => c.Consumer.ImplementationType != typeof(Consumer1)
&& c.Consumer.ImplementationType != typeof(ServiceWithCaching));
container.RegisterConditional<IService, Service>(c => !c.Handled);