2010-07-21 3 views
12

J'ai quelques projets basés sur NHibernate 1.2 et j'aimerais les ajouter à une solution .NET 4.0, mais j'obtiens une exception AmbiguousMatchException.
Peu importe si ces projets sont ciblés sur le cadre 2.0 ou 4.0.
Cela fonctionne si je les ajoute à une solution .NET 3.5.NHibernate 1.2 dans une solution .NET 4.0

Est-ce que quelqu'un a de l'expérience avec ça?

Voici l'exception:

[AmbiguousMatchException: Ambiguous match found.] 
    System.RuntimeType.GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers) +9607924 
    System.Type.GetMethod(String name) +29 
    Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST.LockBlockExpression.Emit(IEasyMember member, ILGenerator gen) +192 
    Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST.ExpressionStatement.Emit(IEasyMember member, ILGenerator gen) +52 
    Castle.DynamicProxy.Builder.CodeBuilder.AbstractCodeBuilder.Generate(IEasyMember member, ILGenerator il) +370 
    Castle.DynamicProxy.Builder.CodeBuilder.EasyMethod.Generate() +71 
    Castle.DynamicProxy.Builder.CodeBuilder.AbstractEasyType.EnsureBuildersAreInAValidState() +706 
    Castle.DynamicProxy.Builder.CodeBuilder.AbstractEasyType.BuildType() +90 
    Castle.DynamicProxy.Builder.CodeGenerators.BaseCodeGenerator.CreateType() +55 
    Castle.DynamicProxy.Builder.CodeGenerators.ClassProxyGenerator.GenerateCode(Type baseClass, Type[] interfaces) +573 
    Castle.DynamicProxy.Builder.DefaultProxyBuilder.CreateClassProxy(Type theClass, Type[] interfaces) +87 
    Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type baseClass, Type[] interfaces, IInterceptor interceptor, Boolean checkAbstract, Object[] argumentsForConstructor) +116 
    NHibernate.Proxy.CastleProxyFactory.GetProxy(Object id, ISessionImplementor session) +136 

[HibernateException: Creating a proxy instance failed] 
    NHibernate.Proxy.CastleProxyFactory.GetProxy(Object id, ISessionImplementor session) +270 
    NHibernate.Persister.Entity.AbstractEntityPersister.CreateProxy(Object id, ISessionImplementor session) +17 
    NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation) +354 
    NHibernate.Impl.SessionImpl.InternalLoad(Type clazz, Object id, Boolean eager, Boolean isNullable) +52 
    NHibernate.Type.EntityType.ResolveIdentifier(Object id, ISessionImplementor session) +37 
    NHibernate.Type.EntityType.ResolveIdentifier(Object id, ISessionImplementor session, Object owner) +55 
    NHibernate.Impl.SessionImpl.InitializeEntity(Object obj) +187 
    NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session) +229 
    NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +702 
    NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +62 
    NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +51 
    NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) +18 
    NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet querySpaces, IType[] resultTypes) +81 
    NHibernate.Loader.Criteria.CriteriaLoader.List(ISessionImplementor session) +36 
    NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria, IList results) +315 
    NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria) +66 
    NHibernate.Impl.CriteriaImpl.List() +54 
    [my code calling Criteria.List()] 
+1

Vous devrez le déboguer pour trouver une correspondance ambiguë de quoi. Si c'est vraiment une chose .NET 4, il semble que Castle utilise la réflexion pour rechercher une méthode .NET spécifique dans l'exécution sans liste d'arguments et que .NET 4 fournit maintenant plusieurs surcharges de cette méthode (!). Si vous pouvez déboguer dans NHibernate et/ou Castle (c'est-à-dire si vous avez des PDB, ou si vous les avez construits vous-même) cela devrait être assez simple. – Rup

+0

Rup, vous avez raison. J'ai vu dans [1] que Castle cherche Look.Enter, mais à partir de .NET 4.0 cette méthode a 2 signatures. Je ne suis pas en mesure de trouver les sources de Castle DynamicProxy 1.1.5, je ne peux pas le recompiler. Merci quand même. [1] http://www.symbolsource.org/Public/Metadata/Project/Castle/1.0-RC3/Debug/All/Castle.DynamicProxy/Castle.DynamicProxy/Builder/CodeBuilder/SimpleAST/LockBlockExpression.cs – ssambi

+1

vous peut obtenir l'ancien code de Castle ici: http://github.com/castleproject/castle –

Répondre

14

Suite au commentaire de Rup, j'ai résolu de changer les sources de Castle DynamicProxy 1.1.5 et de recompiler.
Le problème est d'invoquer avec réflexion la méthode System.Threading.Monitor.Enter sans spécifier d'arguments (parce que dans .NET 2.0 il n'y a qu'une seule signature), mais depuis .NET 4.0 cette méthode a deux surcharges.

J'ai modifié la Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST.LockBlockExpression de classe, en changeant la ligne

gen.Emit(OpCodes.Call, typeof(Monitor).GetMethod("Enter")); 

avec la ligne

gen.Emit(OpCodes.Call, typeof(Monitor).GetMethod("Enter", new Type[] { typeof(object) })); 

J'ai les sources de NHibernate 1.2 from SourceForge pendant que je démonté le code de Castle DynamicProxy 1.1.5 avec Reflector.

+0

vous devriez accepter cette réponse. –

+0

J'ai accepté la réponse, merci Mauricio – ssambi

+1

J'ai la source 1.1.5 réelle dans une branche de fournisseur dans mon dépôt SVN et l'ai postée en réponse à une question sur une liste de diffusion ici. Pas de garanties :) http://groups.google.com/group/mybatisnet-user/browse_thread/thread/a60a0b5fd29a1ff9 –

3

1.x NHibernate est tout à fait non pris en charge à ce stade. Vous devriez mettre à niveau au moins vers 2.1.2.

Dans tous les cas, le message d'erreur indique clairement que le problème n'est pas dans NHibernate lui-même, mais dans Castle DynamicProxy.

+0

Le problème n'est pas avec l'ancien DP lui-même. C'est vieux DP (construit pour. Net 1.1) fonctionnant sur .NET 4 :) –

+0

Yup, c'est ce que j'ai pensé :-) –