Skip to content

Generics

Peter Csajtai edited this page Jul 21, 2020 · 21 revisions

With stashbox you have the option to register open generic types, which gives you the flexibility of choosing the closed generic parameter later at resolution time.

interface IDrow<TLeftHand, TRightHand> 
{
}

class Drow<TLeftHand, TRightHand> : IDrow<TLeftHand, TRightHand> 
{
    public Drow(TLeftHand leftHand, TRightHand rightHand)
    {
    }
}

container.Register(typeof(IDrow<,>), typeof(Drow<,>))
         .Register<Twinkle>()
         .Register<Icingdeath>();

var drizzt = container.Resolve<IDrow<Twinkle, Icingdeath>>();

A registered concrete generic type has always priority over an open generic type.

Dependency selection by contraints

This example shows that the container chooses ConstraintTest1 because its generic argument constraint satisfies the interface implemented by the requested ConstraintArgument.

interface IConstraint { }
interface IConstraint1 { }
interface IConstraintTest<T> { }

class ConstraintTest<T> : IConstraintTest<T> where T : IConstraint { }
class ConstraintTest1<T> : IConstraintTest<T> where T : IConstraint1 { }
class ConstraintArgument : IConstraint1 { }

using (var container = new StashboxContainer())
{
     var inst = container.Register(typeof(IConstraintTest<>), typeof(ConstraintTest<>))
                         .Register(typeof(IConstraintTest<>), typeof(ConstraintTest1<>))
                         .Resolve<IConstraintTest<ConstraintArgument>>();

     Assert.IsInstanceOfType(inst, typeof(ConstraintTest1<ConstraintArgument>));
}

Collection filters by constraints

This example shows that the container is filtering out the services from the returned collection which doesn't satisfy the given generic constraint that needed to create the closed generic type.

using (var container = new StashboxContainer())
{
    var inst = container.Register(typeof(IConstraintTest<>), typeof(ConstraintTest<>));
                        .Register(typeof(IConstraintTest<>), typeof(ConstraintTest2<>))
                        .ResolveAll<IConstraintTest<ConstraintArgument>>().ToArray();

    Assert.AreEqual(1, inst.Length);
}