2010-11-17 18 views
2

Est-ce que quelqu'un sait s'il est possible de contrôler les noms des types générés via Castle DynamicProxy? J'espérais profiter de la possibilité de conserver l'assembly généré par Castle pour ajouter quelques classes supplémentaires avec certaines fonctionnalités spécifiques à mon projet, mais j'aimerais pouvoir contrôler les noms de ces types de proxy générés. Toute aide serait grandement appréciée.Castle DynamicProxy a généré les noms de classes

Je prévois réellement de persister des instances de ces classes ainsi que des instances des classes originales qui sont les sources des proxies avec NHibernate. Donc, j'ai besoin de ces noms pour être cohérent à travers plusieurs générations de l'assemblée.

Répondre

3

J'ai fait quelques recherches intéressantes. La spécification des noms de proxy semble être possible en utilisant un INamingScope, mais il est loin d'être simple d'insérer l'INamingScope. Vous devez créer votre propre ProxyFactoryFactory, ce qui créerait une ProxyFactory identique à NHibernate.ByteCode.Castle.ProxyFactory, sauf initierait 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; } 
} 

Honnêtement, je n'ai pas essayé d'exécuter ou de compiler tout cela. Juste en train de creuser le code source de NHibernate et Castle.Core. Espérons que cela vous donne quelques idées ...

+0

Mec, tu es mon héros. – yonkz

+0

Je vais essayer dans les prochains jours et vous dire comment ça se passe. – yonkz

+0

Sneaky très sournois;) Vous avez noté correctement __it est loin d'être simple et pour une raison. Ce n'était pas exactement destiné à être annulé.De toute façon si vous le faites, il y a une hypothèse (ne pas se souvenir si documenté) que la portée de nommage sera cohérente - pour donné 'suggestedName' il ** retournera toujours ** le même nom unique (évidemment il doit être unique donc encore , si vous appelez la méthode deux fois, elle doit toujours retourner la même seconde valeur, et ainsi de suite). Le processus de désérialisation en dépend. –

0

Jetez un coup d'œil au projet ProxyGenerators dans NHContrib. Il vous permet de pré-générer les proxies de chargement paresseux de NHibernate.

http://nhforge.org/wikis/proxygenerators10/default.aspx

Que vous utilisiez les ProxyGenerators ou non, vous intégrez vos procurations personnalisés dans NHibernate via Factory Factory Proxy. Dans hibernate.cfg.xml:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 
    <session-factory> 
    <property name="proxyfactory.factory_class">YOUR_PROXY_FACTORY_FACTORY</property> 
    </session-factory> 
</hibernate-configuration> 
+0

Je pense que vous ne comprenez pas mon but. Je ne veux pas changer le fonctionnement des proxies NHibernate. Je veux un autre ensemble de classes persistantes dérivées de classes persistantes existantes avec un comportement supplémentaire. Donc, si j'ai une classe nommée Product, je veux générer une classe proxy appelée ProductOverride dérivée de Product, qui va changer les comportements, mais qui a aussi des mappages de base de données légèrement différents. Donc, ma question est plus sur DynamicProxy et pas vraiment sur NHibernate du tout. Je réalise que je pourrais accomplir cela grâce à une génération de code, mais je préférerais que cela se produise à l'exécution. – yonkz

+0

Pourquoi n'utilisez-vous pas les mappages d'héritage NHibernate standard pour accomplir ceci? Pourquoi avez-vous même besoin de déranger avec des proxies dynamiques? –

+0

Parce que je ne veux pas maintenir ces classes. Je ne cherche pas un design alternatif. J'en ai plusieurs. Création de classes réelles manuellement, création de classes réelles via la génération de code. Ils entraînent tous deux le double de l'effort de maintenance. Je cherche à éviter cela. – yonkz