Skip to content

Improve support passing for constructor arguments to Resolve() #78

@darkcamper

Description

@darkcamper

Hi! I was looking for a replacement for Ninject compatible with ASP Net Core and came across Grace.

I found it really appealing because it has nice features from Autofac such as lightweight lifetime scopes and the contextual injection I like so much from Ninject (and it's alive!). While I was writing some tests to learn how to do the same things I do with other DI containers I reached a dead end when trying to simulate Ninject's ConstructorArgument (and the other IConstructorArgument implementations).

Initially I was more or less able to replace them by using the extraData parameter of the DependencyInjectionContainer.Locate method but soon I found some cases I couldn't find a solution for this case:

    public class SomeClass
    {
        private readonly A _someA;
        private readonly int _someInteger;
        private readonly B _someB;

        public SomeClass(B someB)   
        {
            _someB = someB;
        }

        public SomeClass(B someB,int someInt) : this(someB)
        {
            _someInteger = someInt;
        }

        public SomeClass(B someB, int someInt, A someA) : this(someB,someInt)
        {
            _someA = someA;
        }

    }
    
    
    static void Main(string[] args)
    {

        var container = new DependencyInjectionContainer();
        container.Configure(c =>
        {
            c.Export<SomeClass>();
            c.Export<B>();
        });
        
        var instance = container.Locate<SomeClass>(new { someInt = 10 });
    }

I expected that SomeClass would be instantiated using the second constructor as the container has an export for "B" and knows a value for the "someInt" parameter, but the chosen constructor was the first one. In this scenario using "ConstructorSelectionMethod.MostParameters" wouldn't do the trick because it would use the last constructor and fail since I don't have an export for "A" in my container.

Looking at the sources it seems that the constructor selector doesn't use contextual info (extradata) when deciding the best constructor, and you couldn't easily change this because "IWrapperOrExportActivationStrategy.GetActivationStrategyDelegate" doesn't receive an "IInjectionContext".

What do you think on expanding the delegate generation and constructor selection by allowing usage of injection context? And maybe also adding support for additional constructor arguments like Ninject's "TypeMatchingConstructorArgument". By the way if I'm mistaken and all I'm saying is already possible please forgive my ignorance 😄

Whew! Sorry for the wall of text.

Best regards and thank you for this cool project!

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions