Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExcludeTypeFromAutoRegistration dosn't do anything for ChildContainers #299

Open
Warstone opened this issue Nov 10, 2022 · 5 comments
Open

Comments

@Warstone
Copy link

public class B
{
    public B(A a)
    {
        A = a;
    }

    public A A;
}
public class A
{
    public int Value;
}

public static class Program
{
    public static void Main()
    {
        var container = new DependencyInjectionContainer();
        container.Configure(c =>
        {
            // c.ExcludeTypeFromAutoRegistration(typeof(A)); // Uncomment this line for correct answer
        });

        var origA = new A() { Value = 5 };
        var subContainer = container.CreateChildScope();
        subContainer.Configure(c =>
        {
            c.ExcludeTypeFromAutoRegistration(typeof(A)); // This line is useless
        });

        B obj = subContainer.Locate<B>(new {
            a = origA
        });
        
        Console.Write($"obj A val = {obj.A.Value}"); // This will write "obj A val = 0", expected result: "obj A val = 5"
    }
}

Here is the code illustrating example. If I exclude AutoRegistration in child container (I want to override parent behaviour) it won't work. I need to exclude it in parent container.

So Excluding in child containers dosn't do anything.

@ipjohnson
Copy link
Owner

I'll take a look this weekend but ultimately I believe what you're seeing is that auto registration is independent between container & child container. So the request bubble up to the root container where the auto registration resolves.

@Warstone
Copy link
Author

I think same, but it's not expected behavior for me. Nested container must block such things and I've expected to see 5 in result

@Warstone
Copy link
Author

Warstone commented Nov 22, 2022

If you want to make it works as I expect, than in subContainer you could register factory like this:

c.ExportFactory<IInjectionContext, B>(scope => new B((A)scope.GetExtraData("a")));

But it still wired that something dosn't work as intended

@Warstone
Copy link
Author

Warstone commented Nov 22, 2022

public class B
{
    public B(IA a)
    {
        A = a;
    }

    public IA A;
}

public interface IA
{
    public int Value {get; set; }
}
public class A: IA
{
    public int Value { get; set; }
}

...

        var container = new DependencyInjectionContainer();
        container.Configure(c =>
        {
            c.Export<A>().As<IA>();
        });

        var origA = new A() { Value = 5 };
        var subContainer = container.CreateChildScope();
        subContainer.Configure(c =>
        {
            c.ExportInstance(origA).As<IA>().Lifestyle.Singleton();
            // c.Export<B>().As<B>(); // This line will fix this and give same Values
        });

        B obj = subContainer.Locate<B>();
        IA obj2 = subContainer.Locate<IA>();
        
        Console.Write($"B.A.Value = {obj.A.Value}, IA.Value = {obj2.Value}"); // B.A.Value = 0, IA.Value = 5

It looks like childContainers broken completely.

@ipjohnson
Copy link
Owner

Essentially what you're seeing is that auto registration is done in the root container. I'll say up front that the child container support is not 100% compatible with what you'll see in other containers like Unity or AutoFac. Most of these decisions are rooted in the fact Grace use Linq expressions to build factories for performance but they don't take dynamic exports into consideration like child containers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants