Description
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)