Skip to content

Instantly share code, notes, and snippets.

@adamjasinski
Created April 9, 2015 12:59
Show Gist options
  • Save adamjasinski/d9ccc7cb2373ad844c65 to your computer and use it in GitHub Desktop.
Save adamjasinski/d9ccc7cb2373ad844c65 to your computer and use it in GitHub Desktop.
/// <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