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
AMessageService
--> notify is a NotifyComposite
with the types EmailChannelA
and ChatChannel
BMessageService
--> notify is a NotifyComposite
with the types EmailChannelB
and ChatChannel
Current Result
AMessageService
--> notify is a NotifyComposite
with the types EmailChannelA
and ChatChannel
BMessageService
--> notify is a NotifyComposite
with the types EmailChannelA
and ChatChannel
Other findings
container.Register<IHandle, AMessageService>(serviceKey: nameof(AMessageService))
it works. Seems like, when the setup.condition function is called the resolution context is always the first registered IHandle
, but I don't know why.openResolutionScope
, but that did not helpMade.Of
in AMessageService
and BMessageService
would cause duplicate lines of code and I want to avoid that. E.g. for all further INotify
implementations that are not tied to a condition and should be injected for all services)How can to register this correctly?
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));