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

Child container fails to resolve registered open generic interface after parent container fails to resolve it #288

Open
rjgotten opened this issue Nov 9, 2020 · 3 comments
Assignees
Labels

Comments

@rjgotten
Copy link

rjgotten commented Nov 9, 2020

Description

Assume a root container and a child container where the child has an open generic interface->type mapping registered.

  • Resolving the interface from the child container works.
    This is expected, since it has the mapping.
  • Resolving the interface from the parent container throws a ResolutionFailedException.
    This is expected, since it does not have the mapping.
  • Resolving the interface from the child container after having attempted to resolve it from the parent container will cause the child container to also throw a ResolutionFailedException because the interface is not mapped.
    This is unexpected (and wrong: it clearly is mapped).

Reproduction

An NUnit unit test project that illustrates the above is available at
https://github.com/NetMatch/unity-358-repro

Versions

NuGet Unity package 5.11.7

@rjgotten
Copy link
Author

rjgotten commented Nov 9, 2020

I wonder if this is a variant of unitycontainer/microsoft-dependency-injection#14 which was resolved in 2018, and if it's not basically the same problem:

  1. Child container doesn't have open-to-closed mapping;
  2. Child container looks up at parent container;
  3. Parent container does have open-to-closed type mapping (which previously failed)
  4. Closed type resolves on parent container;
  5. But parent container doesn't have interface actually mapped; so we always get ResolutionFailedException

@ENikS
Copy link
Contributor

ENikS commented Nov 17, 2020

Unity creates a registration and a pipeline for each type. If type can not be created, the pipeline throws an exception.
When you resolve in child, the container will check registrations from that child to the root container and if registration is found it will be using it.

So, in your case faulty registration is being picked up by the child.

You could override registration in child to prevent the exception.

@rjgotten
Copy link
Author

rjgotten commented Nov 17, 2020

You could override registration in child to prevent the exception.

The open generic registration is done on the child container.

The problem starts when you attempt to resolve a closed instance of that generic type in the parent container, before you attempt to resolve that same closed instance in the child container.

At that point something caches the broken resolve in the parent container, and attempting to then resolve the same type in the child container -- where it should succeed -- is broken as well, presumably because the child container sees the cached broken resolve for the closed generic type on the parent, before it runs through the open generic on the child.


I guess the issue boils down to open generic type registrations on child containers not overruling closed generic type resolves and/or registrations on parents, which I think -- if this is indeed the case -- would be an architectural flaw.

If you specify an open generic type mapping, that means you're specifying you'll be handling all closed generic forms of that type and thus should be overriding all closed forms on parent containers as well.

@ENikS ENikS self-assigned this Nov 17, 2020
@ENikS ENikS transferred this issue from unitycontainer/unity Nov 17, 2020
@ENikS ENikS added the Bug 🐛 label Nov 17, 2020
@ENikS ENikS assigned ENikS and unassigned ENikS Nov 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants