ipjohnson / Grace

Grace is a feature rich dependency injection container library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Property injection not populated when target instance is also in container

dtkujawski opened this issue · comments

This is a bit tricky to explain with words, but I think the code makes it easier to see. For reference, take the following interfaces and classes for this example (as simplified as I could boil everything down):

        public interface IChild { }
        public class Child : IChild { }

        public interface IParent { }
        public class Parent : IParent
        {
            [Import] public IChild Child { get; set; }
        }

In a scenario where I register Child/IChild in the container and then get an instance of Parent directly, everything is wired up just fine:

        var container = new DependencyInjectionContainer();
        container.Configure(c => c.Export<Child>().As<IChild>());

        var parent = container.Locate<Parent>();
        Assert.NotNull(parent.Child);                  //PASSES

But, if I were to also put Parent/IParent in the container and then call Locate the DI would not resolve and the Child property would be null:

        var container = new DependencyInjectionContainer();
        container.Configure(c => c.Export<Child>().As<IChild>());
        container.Configure(c => c.Export<Parent>().As<IParent>());

        var parent = container.Locate<IParent>();
        Assert.NotNull((parent as Parent).Child);      //FAILS

Even in the case where I register the class directly (not the IParent interface, but the Parent type) it still fails:

        var container = new DependencyInjectionContainer();
        container.Configure(c => c.Export<Child>().As<IChild>());
        container.Configure(c => c.Export<Parent>());

        var parent = container.Locate<Parent>();
        Assert.NotNull(parent.Child);                 //FAILS

Is this expected behavior?

NOTE: If I add a constructor-based DI to the Parent class, everything works fine.

Hi @dtkujawski, while it seems kind of odd it's actually expected behavior but there are work arounds. Let me explain why it doesn't work first.

  • First case works because parent is being auto resolved by the container and without any registration it inspects the class to see if there are any hints on how to construct it
  • Second and third case you're using the fluent registration and by default it expects all configuration to come through the fluent interface.

You can add .ProcessAttributes() to the end of your fluent call if it's a one off. Or you can add an IActivationStrategyInspector and do it automatically. I've added a test case here as an example of how to do it.

@ipjohnson, that worked perfectly. Thank you very much!