Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,131 | Comments: 45,568

filter by tags archive

Can you hack this out? Revised

time to read 2 min | 359 words

It appears that I made this challenge a bit too hard, I wrote it in haste and didn’t check that it all works. Here is the new code, it is almost the same as the first, but now it doesn’t check the typeof(T) (for which there is no interception path), but the provided runnerType instead.

internal interface IRunner
void Execute();

public sealed class AssemblyRunner : IRunner
void IRunner.Execute()

public class CompositeRunner
private readonly Type runnerType;

public CompositeRunner(Type runnerType)
this.runnerType = runnerType;

public void Execute()
if (!typeof(IRunner).IsAssignableFrom(runnerType))
throw new InvalidOperationException("invalid type");
var runner = (IRunner)Activator.CreateInstance(runnerType);

Sorry about that image

Look at the future posts for hints for that.


Omer Mor

Now THAT'S easy!

I have a great solution for this, but it doesn't fit in this comment. :-)

Alex Simkin

OK. You already forced me to look at ProfilingSqlProviderProxyType, so I cannot participate.

Pierre Fermat


Been There, Done That!


Stefan Wenig

now it seems almost simple. you can create a RealProxy for IRunner

class MyProxy : RealProxy {

MyProxy() : base (Type.GetType ("IRunner...")

and put a custom ProxyAttribute on the type you pass (must be derived from ContextBoundObject). Some fumbling with Invoke(), that should basically be it...

Ayende Rahien


Write the code, there is still one trip wire there.

Fabian Schmied

The one trip still there is the " if (!typeof(IRunner).IsAssignableFrom(runnerType))" check.

And this can be solved by:

  • subclassing System.Type (in actual C# code, no hackery required) and

  • overriding UnderlyingType

    • to return typeof (IRunner) on the first call and

    • typeof (MyContextBoundObject) on the second call.

Strangely, this works, it really does. At the moment, at least. Aren't you afraid to actually sell a piece of software based on this hack? :)

Stefan Wenig
Oh right, I was so p***ed about the cast in CreateInstance
<t that I forgot about that one. Couldn't find a better solution than Fabian either, everything else seems to end up in something internal/sealed. (I even had to look at the SSCLR, because reflector screws up in Type.IsAssignableFrom... enough unnatural acts for this month!)
So is this it, or is there a better way?
Ayende Rahien


I am really scared by that, yes.

OTOH, what other choice do I have?

Stefan Wenig

CreateInstance(Of T) that is. No angle brackets, must be a VB lover's blog ;-)

BTW, just when I realized that R# can't go all the way when subclassing Type via delegation to a member, I discoverd System.Reflection.TypeDelegator. Nice!

Insanely, I agree with you Ayende. If this changes in vNext, you'll just have to come up with another unnatural hack. Still better than Profiling APIs by any means.

Frank Quednau

Yes, this looks more doable.

@Omer nice Fermat analogy there :)

This hack just goes to show that there is no true privacy in such a system, simplest example being how easy it is to instantiate a type through a private constructor. I wonder how the CLR would want to avoid such things from happening. After all it needs to interrogate the type to answer whether it is assignable and Type is an abstract class in which you can override stuff.

Jay R. Wren

I CAN'T TAKE IT ANYMORE! I've spent too many hours on this already... well, ok... only 2.5, but that is too many for me.

Once Fabian suggested deriving from Type, I got past the IsAssignableFrom... And I'm using ContextBoundObject to return a RealProxy from Activator.CreateInstance, but I cannot get past the unable to cast transparent proxy to type IRunner

What is the solution?

Fabian Schmied

Jay, implement IRemotingTypeInfo on your real proxy, then the cast isn't an issue any longer.

Jay R. Wren


Thanks. I had that, but removed it when I went with a different approach.

... I'm learning WAY too much here :)

Omer Mor

I tried to implement the solution according to the comments, but I still fail to get past the "unable to cast transparent proxy" part.

Can you give me a hint?

This is my solution so far:

public class Program


private static void Main()


    var myType = new MyType


    var compositeRunner = new CompositeRunner(myType);




public class MyProxyAttribute : ProxyAttribute


public override RealProxy CreateProxy(ObjRef objRef1, Type serverType, object serverObject,

                                      Context serverContext)


    Type classToProxy = typeof (AssemblyRunner).GetInterface("ThirdParty.IRunner");

    return new MyProxy(classToProxy);




public class MySubclass : ContextBoundObject



public class MyType{T} : TypeDelegator


private bool m_firstTime = true;

public MyType() : base(typeof (T))



public override Type UnderlyingSystemType




        if (m_firstTime)


            m_firstTime = false;

            return typeof (T);


        return typeof (MySubclass);




public class MyProxy : RealProxy, IRemotingTypeInfo


public MyProxy(Type classToProxy) : base(classToProxy)



public bool CanCastTo(Type fromType, object o)


    return true;


public string TypeName { get; set; }

public override IMessage Invoke(IMessage msg)


    return msg;




Done it, so as hard as I thought.

This challenge suddenly much easier without the generic type.

Basically, I use:

  • TypeDelegator to pass IsAssignableFrom

  • ContextBoundObject, ProxyAttribute and RealProxy to create an interceptor for the instance.

  • IRemotingTypeInfo to pass the type casting check.

All method call are then redirected to the real runner.

I don't see any chance that there will be any change that will cause this code not to run in next versions of .NET Framework.

TypeDelegator is used for the purpose it was created, that is delegating the type information.

Proxy is used to redirect messages, which is also what it was created for.

The only place that I used a real hack is in the GetInterfaces of TypeDelegator when I use StackFrame to see who called the method to return the appropriate result.


So there is no solution for the original one? I was really curious on how you hacked the typeof(T) :P


Comment preview

Comments have been closed on this topic.


  1. RavenDB Conference 2016–Slides - 2 hours from now
  2. Proposed solution to the low level interview question - about one day from now

There are posts all the way to Jun 02, 2016


  1. The design of RavenDB 4.0 (14):
    26 May 2016 - The client side
  2. RavenDB 3.5 whirl wind tour (14):
    25 May 2016 - Got anything to declare, ya smuggler?
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series



Main feed Feed Stats
Comments feed   Comments Feed Stats