Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add an extra interface using Castle Dynamic Proxy 2?

I would like to create a dynamic proxy to an existing type, but add an implementation of a new interface, that isn't already declared on the target type. I can't figure out how to achieve this. Any ideas?

like image 824
James L Avatar asked May 30 '11 19:05

James L


1 Answers

You can use the overload of ProxyGenerator.CreateClassProxy() that has the additionalInterfacesToProxy parameter. For example, if you had a class with a string name property and wanted to add an IEnumerable<char> to it that enumerates the name's characters, you could do it like this:

public class Foo
{
    public virtual string Name { get; protected set; }

    public Foo()
    {
        Name = "Foo";
    }
}

class FooInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        if (invocation.Method == typeof(IEnumerable<char>).GetMethod("GetEnumerator")
            || invocation.Method == typeof(IEnumerable).GetMethod("GetEnumerator"))
            invocation.ReturnValue = ((Foo)invocation.Proxy).Name.GetEnumerator();
        else
            invocation.Proceed();
    }
}

…

var proxy = new ProxyGenerator().CreateClassProxy(
    typeof(Foo), new[] { typeof(IEnumerable<char>) }, new FooInterceptor());

Console.WriteLine(((Foo)proxy).Name);
foreach (var c in ((IEnumerable<char>)proxy))
    Console.WriteLine(c);

Note that the Name property doesn't have to be virtual here, if you don't want to proxy it.

like image 84
svick Avatar answered Sep 27 '22 00:09

svick