.netdependency-injectiondryioc

DryIoc: setup condition yields unexpected parent


I am using DryIoc version 5.0.0 with .net framework and I have the following classes:

public class AMessageService : IHandle {
   public AMessageService (INotify notify) {
     //...
   }
}
public class BMessageService : IHandle {
   public BMessageService (INotify notify) {
     //...
   }
}

and the following registrations:

   // ...
   container.Register<IHandle, AMessageService>(serviceKey: nameof(AMessageService));
   container.Register<IHandle, BMessageService>(serviceKey: nameof(BMessageService));

   // ...

I can resolve all available IHandle implementations in my constructor like this:

public SequentialEventAggregator(params IHandle[] handlers) // <-- yields AMessageService and BMessageService

Now I want to register multiple INotify implementations. I figured I can create a NotifyComposite class that gets an enumeration of INotify implementations

public class NotifyComposite: INotify {
   private readonly IEnumerable<INotify> _notificators;
   public NotifyComposite(IEnumerable<INotify> notificators) {
        _notificators = notificators;
   }

   public Notify():void {
     _notificators.ForEach(n => n.Notify());
  }
}
   // ...
   container.Register<IHandle, AMessageService>(serviceKey: nameof(AMessageService));
   container.Register<IHandle, BMessageService>(serviceKey: nameof(BMessageService));

   container.Register<INotify, NotifyComposite>();
   // ...

But now I am stuck trying to register multiple other INotify implementation, that have a setup condition.

   // ...
   container.Register<IHandle, AMessageService>(serviceKey: nameof(AMessageService));
   container.Register<IHandle, BMessageService>(serviceKey: nameof(BMessageService));

   container.Register<INotify, NotifyComposite>();

   // using Parent.Parent because the first Parent is NotifyComposite
   container.Register<INotify, EmailChannelA>(setup: Setup.With(condition: r => r.Parent.Parent.ImplementationType == typeof(AMessageService));
   container.Register<INotify, EmailChannelB>(setup: Setup.With(condition: r => r.Parent.Parent.ImplementationType == typeof(BMessageService)); // <-- does not work properly
   container.Register<INotify, ChatChannel>();
   // ...

Expectation

Current Result

Other findings

How can to register this correctly?


Solution

  • I solved this issue: The problem must be due to caching and registering NotifyComposite without additional settings. Adding asResolutionCall or openResolutionScope to true for NotifyComposite ()causes the wanted behaviour.

    Fix: container.Register<INotify, NotifyComposite>(setup: Setup.With(asResolutionCall: true));