Search code examples
c#castle-dynamicproxy

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?


Solution

  • 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.