【问题标题】:NHibernate 1.2 in a .NET 4.0 solution.NET 4.0 解决方案中的 NHibernate 1.2
【发布时间】:2010-07-21 15:45:02
【问题描述】:

我有一些基于 NHibernate 1.2 的项目,我想将它们添加到 .NET 4.0 解决方案中,但我得到了 AmbiguousMatchException。
无论这些项目是针对 2.0 还是 4.0 框架。
如果我将它们添加到 .NET 3.5 解决方案中,它会起作用。

有人有这方面的经验吗?

这里是个例外:

[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()]

【问题讨论】:

  • 您需要对其进行调试以找出不明确的匹配项。如果这真的是 .NET 4 的事情,听起来 Castle 正在使用反射在运行时中查找特定的 .NET 方法,而没有 arg 列表,并且 .NET 4 现在提供了该方法的多个重载(!)。如果您可以调试 NHibernate 和/或 Castle(即,如果您有 PDB,或者如果您自己构建它们),这应该相当简单。
  • 鲁普,你是对的。我在 [1] 中看到 Castle 正在查找 Monitor.Enter,但从 .NET 4.0 开始,该方法有 2 个签名。我无法找到 Castle DynamicProxy 1.1.5 的源代码,我无法重新编译它。还是非常感谢。 [1]symbolsource.org/Public/Metadata/Project/Castle/1.0-RC3/Debug/…
  • 您可以在这里获取 Castle 的旧代码:github.com/castleproject/castle

标签: nhibernate .net-4.0


【解决方案1】:

根据 Rup 的评论,我解决了更改 Castle DynamicProxy 1.1.5 的源并重新编译的问题。
问题是使用反射调用方法 System.Threading.Monitor.Enter 而不指定参数(这是因为在 .NET 2.0 中只有 1 个签名),但由于 .NET 4.0 该方法有 2 个重载。

我修改了类 Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST.LockBlockExpression,改变了行

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

与行

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

我有 NHibernate 1.2 from SourceForge 的源代码,同时我用 Reflector 反汇编了 Castle DynamicProxy 1.1.5 的代码。

【讨论】:

  • 我在我的 SVN 存储库的供应商分支中有实际的 1.1.5 源代码,并将其发布以回答此处邮件列表中的问题。不保证 :) groups.google.com/group/mybatisnet-user/browse_thread/thread/…
  • 这对我也有用,真的救了我们的培根(有一个依赖 DynamicProxy 的第三方 DLL)
  • 同样的解决方案适用于 iBatis 1.6,它使用 Castle.DynamicProxy。一个非常有用的答案 - 谢谢。
【解决方案2】:

NHibernate 1.x 目前完全不受支持。您应该至少升级到 2.1.2。

无论如何,从错误消息中可以清楚地看出问题不在于 NHibernate 本身,而在于 Castle DynamicProxy。

【讨论】:

  • 问题不在于旧 DP 本身。它是在 .NET 4 上运行的旧 DP(为 .net 1.1 构建):)
  • 是的,我就是这么想的 :-)
猜你喜欢
  • 2011-06-14
  • 2011-03-29
  • 2012-12-30
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多