Skip to content

Improving GenericParameter and OptionalGenericParameter injection parameters #294

Open

Description

@ENikS

Generic Parameter injection members

Unity implements several classes representing generic parameters:

  • GenericParameter
  • OptionalGenericParameter

These are useful when registering generic types. For example, consider the following two types:

public class TestType<TDependency>
{
    public TestType([Dependency] TDependency value) { }
    ...
}


public class NamedTestType<TDependency>
{
    public NamedTestType([Dependency("name")] TDependency value) { }
    ...
}

Both of these classes have constructors that import a dependency, but one is anonymous and the other one is named.

To register these types you would do something like this:

Container.RegisterType(typeof(TestType), new InjectionConstructor( new GenericParameter("TDependency")));

Container.RegisterType(typeof(NamedTestType), new InjectionConstructor(new OptionalGenericParameter("TDependency")));

These registrations would instruct Unity to select a constructor taking one parameter and resolve associated value. You register rest of your types:

Container.RegisterInstance("registered")
         .RegisterInstance("name", "named");

and now try to resolve: Container.Resolve<TestType<string>>()

Current Behavior

The container will return a type initialized with the string: "registered". Accordingly, when you resolve Container.Resolve<NamedTestType<string>>() you would expect an instance of NamedTestType type initialized with the string "named", but instead, you will still be getting "registered".

The constructor GenericParameter("TDependency") overrides whatever name is associated with dependency with null. To get correct import you would have to register it like this:

Container.RegisterType(...,(new OptionalGenericParameter("TDependency", "name")));

Problem

This implementation severely limits usability of names in generics and places restrictions on what could be done. Developers need to know at design time all the required names and must manually provide these while coding.

Solution

The proposed solution is to allow default constructor to match any name provided by the type of associated attributes.

Impact

This modification in behavior would create a breaking change and would require changes in code. In cases where dependencies are named, instead of default, Unity will resolve named registrations.
To work around these issues registrations like these GenericParameter("TDependency") should be replaced with GenericParameter("TDependency", null). For Optional dependencies it should be: OptionalGenericParameter("TDependency", null)

Activity

  1. self-assigned this
    on Dec 4, 2020
  2. added this to the 6.0.0 milestone on Dec 4, 2020
  3. added a commit that references this issue on Dec 5, 2020
    bba898f
  4. added a commit that references this issue on Dec 11, 2020
    f40efb2
  5. added and removed
    Enhancement 🔨Improvement of existing features
    on Dec 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions