Skip to content

Improving GenericParameter and OptionalGenericParameter injection parameters #294

Open
@ENikS

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)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions