1

This question is yet another follow-up to a previous question regarding the setup of DryIOC with MediatR and decorators: DryIOC and MediatR: Injection using InResolutionScopeOf for both IAsyncNotificationHandler and IAsyncRequestHandler

In this example, the setup is similar to the one of my previous question, we have requests (IAsyncRequestHandler) and notifications (IAsyncNotificationHandler), and the notifications are being fired from the requests, and both have a dependency on a DbContext with needs to be injected per resolution scope.

What I'm doing now is decorating IAsyncRequestHandler and i'm passing a dependency of type IActionHandler to the decorator using a key. I'm registering the dependency like this:

c.Register<IActionHandler, SomeActionHandler>(serviceKey: "key1");

And then, passing the parameter to the decorator like this:

c.Register(typeof(IAsyncRequestHandler<,>), typeof(Decorator<,>),
               made: Parameters.Of.Type<IActionHandler>(serviceKey: "key1"),
               setup: DryIoc.Setup.Decorator);

Set up like this, the notification is fired from the request handler successfully. However if I add more decorators and change the setup parameter of the decorator to DecoratorWith and specify a condition (even if it simply returns true), the notification isn't fired from the request handler because the DbContext isn't injected successfully into the IAsyncNotificationHandler.

Here is a fiddle which shows the problem https://dotnetfiddle.net/ob0nfA

When debugging, i found out that the condition in DecoratorWith of the first decorator is called twice for the same service type, when there are two registrations. I'm not sure if this is intended or not, however I believe that might be related to the problem, because if I simply return true, then multiple decorators will be registered for the same handler, when there should only be one.

I know I would be able to register the decorator dependencies using Made instead, but in this specific instance keyed registration seems better for my intended setup. So I'd like to know if there's something I'm missing, or in the case that DecoratorWith works as intended by being called more than once for the same service type, I'd like to know if there is a way that I can distinguish the calls, so that i can register the decorator properly only once. Or maybe the problem lies elsewhere entirely.

Thanks

Community
  • 1
  • 1
djed
  • 141
  • 10

1 Answers1

0

Found the reason. In current DryIoc version 2.9.3 adding condition to decorator makes it context dependent (which is true btw). But then context dependent service is injected as resolution call instead expression inlining. Using resolution call here messes up with resolution scopes (not yet 100% clear yet how).

So if I remove the switch to resolution call for context dependent decorators, your code works again.

Fix will be released soon. I will update my answer with the fix version.

Update with fix:

Problem is fixed in DryIoc 2.9.5

dadhi
  • 4,807
  • 19
  • 25
  • it seems at the fourth registration it stops working again. I know it's weird, but it's the count i got on my code, and i tried to replicate it in a fiddle and it stops working again at the fourth registration. Here's the fiddle. https://dotnetfiddle.net/Jnl6IN – djed Dec 13 '16 at 18:23
  • Have an idea why, will check. Thanks for live example. – dadhi Dec 13 '16 at 19:55
  • Issue happens because the deeply nested object graph is split in chunks via Resolve call. Same issue as before but due another reason. I am trying to find what's off with Resolve call in general. – dadhi Dec 14 '16 at 14:55