Generic Matching Configuration

Standard Generic Matching

The basic generic resolution is configured as by specifying an open generic for the type to be resolved (typically an interface type) and another open generic for the concrete type to be instantiated.

Injector.SetGenericResolver(typeof(IEnumerable<>), typeof(List<>));

Constrained Generic Matching

Where fFastInjector makes it more interesting is with the use of constrained matches. By passing in type parameters (1 for each generic type argument), the user can make a generic interface, in this case IEnumerable<>, return a different concrete class depending on the type requested.

Injector.SetGenericResolver(typeof(IEnumerable<>), typeof(List<>));
Injector.SetGenericResolver(typeof(IEnumerable<>), typeof(AnimalList<>), typeof(Animal));
Injector.SetGenericResolver(typeof(IEnumerable<>), typeof(CatList<>), typeof(Cat));


Here are some examples of how different generic types will resolve with the above configuration
var nonanimals = Injector.Resolve<IEnumerable<NonAnimal>>();

Injector.Resolve<IEnumerable<NonAnimal>> gives us a List<NonAnimal> because NonAnimal does not inherit from Animal or Cat, so it matches the List<> configuration, which has no matching constraints and therefore matching everything.

var dogs = Injector.Resolve<IEnumerable<Dog>>();

Injector.Resolve<IEnumerable<Dog>>gives us a AnimalList<Dog> because Dog inherits from Animal but not from Cat

var tigers = Injector.Resolve<IEnumerable<Tiger>>();

Injector.Resolve<IEnumerable<Tiger>> gives us a CatList<Tiger>, because, while Tiger inherits Cat and Cat inherits from Animal, Cat is the more specific type.

Last edited Jan 10, 2015 at 12:27 PM by Grax, version 1


No comments yet.