Search code examples
nhibernatecastle-dynamicproxy

Castle DynamicProxy generated class names


Does anybody know if it is possible to control the names of the types generated through Castle DynamicProxy? I was hoping to take advantage of the ability to persist the assembly generated by Castle to add some additional classes with some specific functionality to my project, but I would like to be able to control the names of these generated proxy types. Any help would be greatly appreciated.

I actually plan to persist instances of these classes as well as instances of the original classes that are the sources of the proxies with NHibernate. So, I need these names to be consistent across multiple generations of the assembly.


Solution

  • I did some interesting digging. Specifying proxy names appears to be possible using an INamingScope, but it is far from straightforward to get the INamingScope wedged in. You would need to create your own ProxyFactoryFactory, which would create a ProxyFactory identical to NHibernate.ByteCode.Castle.ProxyFactory, except it would initilize ProxyGenerator:

    public class CustomProxyFactory : AbstractProxyFactory {
        private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator(new CustomProxyBuilder());
        // remainder of code is identical
    }
    
    public class CustomProxyBuilder : DefaultProxyBuilder {
        public CustomProxyBuilder() : base(new CustomModuleScope()) {}
    }
    
    public class CustomModuleScope : ModuleScope {
        public CustomModuleScope() : base(false, false, new CustomNamingScope(), DEFAULT_ASSEMBLY_NAME, DEFAULT_FILE_NAME, DEFAULT_ASSEMBLY_NAME, DEFAULT_FILE_NAME) {}
    }
    
    public class CustomNamingScope : INamingScope {
        public CustomNamingScope() {}
    
        private CustomNamingScope(INamingScope parent) {
            ParentScope = parent;
        }
    
        public string GetUniqueName(string suggestedName) {
            // your naming logic goes here
        }
    
        public INamingScope SafeSubScope() {
            return new CustomModuleScope(this);
        }
    
        public INamingScope ParentScope { get; private set; }
    }
    

    I honestly haven't tried running or compiling any of this. Just digging through the NHibernate and Castle.Core source code. Hopefully it gives you some ideas...