Created
April 9, 2015 12:59
-
-
Save adamjasinski/d9ccc7cb2373ad844c65 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Registers a specimen builder for open generic type Lazy<>. | |
// When asked for a concrete instance of Lazy<T>, the specimen builder constructs it using a func that returns the concrete inner specimen T using the current fixture. | |
// So it works like: | |
// fixture.Register<Lazy<T>>( fixture, () => new Lazy<T>( () => fixture.CreateAnonymous<T>() ) ); | |
// where T is a runtime type | |
/// </summary> | |
class LazyCustomization : ICustomization | |
{ | |
public void Customize( IFixture fixture ) | |
{ | |
fixture.Customizations.Add( new LazyOpenGenericsSpecimenBuilder() ); | |
} | |
class LazyOpenGenericsSpecimenBuilder : ISpecimenBuilder | |
{ | |
object ISpecimenBuilder.Create( object request, ISpecimenContext context ) | |
{ | |
var typedRequest = request as Type; | |
if ( typedRequest != null && typedRequest.IsGenericType && typedRequest.GetGenericTypeDefinition() == typeof( Lazy<> ) ) | |
{ | |
Type lazilyConstructedType = typedRequest.GetGenericArguments().Single(); | |
Type concreteServiceType = typeof( Lazy<> ).MakeGenericType( lazilyConstructedType ); | |
var builderDelegate = CreateStronglyTypedBuilderDelegate( context, lazilyConstructedType ); | |
return Activator.CreateInstance( concreteServiceType, new object[] { builderDelegate } ); | |
} | |
return new NoSpecimen( request ); | |
} | |
static Delegate CreateStronglyTypedBuilderDelegate( ISpecimenContext context, Type lazilyConstructedType ) | |
{ | |
var builderMethodInfo = context.GetType().GetMethod( "Resolve", BindingFlags.Instance | BindingFlags.Public ); | |
var builderLambda = | |
Expression.Lambda( | |
Expression.Convert( | |
Expression.Call( | |
Expression.Constant( context ), builderMethodInfo, Expression.Constant( lazilyConstructedType ) ), | |
lazilyConstructedType ) ); | |
return builderLambda.Compile(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment