Using CThru to Fake Entire Assemblies – With Real Recursiveness

It sure helps to know all the reflection APIs. Not sure if Eli knows them all by heart, but he sure knows the important ones. He gave me a way to workaround the CThru example.

A short summary: We’re using CThru to Isolate all the types from a selected assembly. What we wanted to do, was do it recursively. You can see what we got to here.

The problem I had was how to create a recursive fake, without knowing the type in advance. Let’s look at this code, which I’m adding to my Aspect class:

// convert to strongly typed
private static object GetRecursiveFake(Type ofType)
{
MethodInfo createRecursiveFakeMethod = typeof (DependentAssemblyAspect)
.GetMethod("CreateRecursiveFake",BindingFlags.Static | BindingFlags.NonPublic)
.MakeGenericMethod(ofType);
return createRecursiveFakeMethod.Invoke(null, null);
}

private static T CreateRecursiveFake<T>()
{
return Isolate.Fake.Instance<T>();
}

The GetRecursiveFake method simply calls the CreateRecursiveFake method through reflection, but using the runtime type. Brilliant!

Let’s look at our aspect event code now (which now calls the GetRecursiveFake method):

public event Action<DuringCallbackEventArgs> OnMethodBehaviorCallback =
e =>
{
foreach (Assembly assembly in AssembliesToFake)
{
Type currentType = assembly.GetType(e.TypeName);
if (currentType != null)
{
MethodInfo mi = currentType.GetMethod(e.MethodName);
if (mi.ReturnType == typeof(void))
e.MethodBehavior = MethodBehaviors.SkipActualMethod;
else
{
e.MethodBehavior = MethodBehaviors.ReturnsCustomValue;
e.ReturnValueOrException = GetRecursiveFake(mi.ReturnType);
}
}
}
};

If our type and method appear in the black list, it looks at the return type of that method. If it’s void, we skip the method (telling Isolator to ignore it). If it returns a value, we return a recursive fake of that return type.

Give it a try!

TOP