Search code examples
dryioc

DryIoc: Different Dependency from different Factory by Condition


I tried something like this:

container.Register<IFactory, WebFactory>(
    serviceKey: "t");

container.Register<IConfigurationProvider>(made: Made.Of(
    r => ServiceInfo.Of<IFactory>(serviceKey: "t"), 
    f => f.Create()), setup: Setup.With(condition:
        req => req.Parent.Enumerate().Any(p => 
            p.ServiceType.Namespace.StartsWith("Namespace"))));


container.Register<IFactory, OtherFactory>(
    serviceKey: "c");

container.Register<IConfigurationProvider>(made: Made.Of(
    r => ServiceInfo.Of<IFactory>(serviceKey: "c"), 
    f => f.Create()), setup: Setup.With(condition:
        req => req.Parent.Enumerate().Any(p => 
            p.ServiceType.Namespace.StartsWith("OtherNamespace"))));


container.Register<IFactory, DefaultFactory>();
container.Register<IConfigurationProvider>(made: Made.Of(
    r => ServiceInfo.Of<IFactory>(), f => f.Create()));         
container.Register<IConfigured, Configured>(made: Made.Of(() =>
    new Configured(Arg.Of<IConfigurationProvider>())));


namespace Namespace {
    class MyService {
        MyService(IConfigured configured) {
        }
    }
}


namespace OtherNamespace {
    class MyOtherService {
        MyOtherService(IConfigured configured) {
        }
    }
}

But DryIoc just injects the last registred one of IConfigurationProvider and ignores the condition. I simplyfied the Code massive and replaced the Names in the configuration (Yes, the Services-Classes are registred).

A better documentation of conditions and RequestInfo would be nice.

EDIT: I now assume, that the problem is my default registration of a factory and DryIoc just uses the last.

EDIT2: What exactly represents RequestInfo? The one who is Requested? So this means Configured? Or is RequestInfo.Parent Configured? What does Enumerate? The whole Dependency Tree?


Solution

  • It is probably a bug in condition used together with instance factory. Need a time to find out.

    The workaround for the moment (DryIoc 2.12.5) will be adding asResolutionCall: true to setups with conditions. Actually it should not be required, and DryIoc should do that automatically behind the scenes to prevent caching of first condition result. That why it is likely a bug.

    Here is the working sample from the comments chat.

    Regarding code in a question, the registrations with condition should be modified like this (reformatted a bit for readability):

    container.Register<IConfigurationProvider>(
        made: Made.Of(r => ServiceInfo.Of<IFactory>(serviceKey: "t"), f => f.Create()), 
        setup: Setup.With(asResolutionCall: true,
            condition: r => r.Parent.Enumerate().Any(
                 p => p.ServiceType.Namespace.StartsWith("Namespace"))));
    
    container.Register<IConfigurationProvider>(
        made: Made.Of(r => ServiceInfo.Of<IFactory>(serviceKey: "c"), f => f.Create()), 
        setup: Setup.With(asResolutionCall: true,
            condition: r => r.Parent.Enumerate().Any(
                 p => p.ServiceType.Namespace.StartsWith("OtherNamespace"))));