升级到Castle Trunk和NHibernate 2.1.0.4000后,我的集成测试崩溃了TestDriven.Net

升级到Castle Trunk和NHibernate 2.1.0.4000后,我的集成测试崩溃了TestDriven.Net,nhibernate,activerecord,castle-monorail,castle,Nhibernate,Activerecord,Castle Monorail,Castle,我有一张旧的单轨/ActiveRecord,我也在做一些工作 最近,我决定将应用程序升级到Castle Trunk&NHibernate 2.1.0.4000 GA,现在我发现运行测试存在一些问题: 首先—当使用TestDriven.Net运行针对数据库的集成测试时,它会完全破坏TestDriven.Net,或者所有测试都完成执行,然后TestDriven.Net挂起。这在升级之前从未发生过 当TestDriven.Net崩溃时,以下是写入事件日志的内容: 故障桶1467169527,类型1 事

我有一张旧的单轨/ActiveRecord,我也在做一些工作

最近,我决定将应用程序升级到Castle Trunk&NHibernate 2.1.0.4000 GA,现在我发现运行测试存在一些问题:

首先—当使用TestDriven.Net运行针对数据库的集成测试时,它会完全破坏TestDriven.Net,或者所有测试都完成执行,然后TestDriven.Net挂起。这在升级之前从未发生过

当TestDriven.Net崩溃时,以下是写入事件日志的内容:

故障桶1467169527,类型1 事件名称:APPCRASH 答复:没有 驾驶室Id:0

问题签名: P1:ProcessInvocation86.exe P2:2.22.2468.0 P3:4a26845c P4:KERNELBASE.dll P5:6.1.7600.16385 P6:4A5BDF P7:E0534F P8:0000b727 第9页: P10:

第二件事-当代理类被Finalize()时,异常被记录下来,如下所示-这似乎是一次记录了几次,即TestDriven.Net崩溃时

以下是异常的堆栈跟踪:

NHibernate.LazyInitializationException:     
Initializing[MyApp.Core.Models.TestExecutionPackage#15d9eb96-faf0-4b4b-9c5c-9cd400065430]-Could not initialize proxy - no Session.
  at NHibernate.Proxy.AbstractLazyInitializer.Initialize()
  at NHibernate.Proxy.AbstractLazyInitializer.GetImplementation()
  at NHibernate.ByteCode.Castle.LazyInitializer.Intercept(IInvocation invocation)
  at Castle.DynamicProxy.AbstractInvocation.Proceed()
  at Castle.Proxies.TestExecutionPackageProxy.Finalize()
同样的行为也会使CI服务器上的MsBuild崩溃

真正奇怪的是,理论上,Finalize()中抛出的异常应该按照MSDN文档进行处理:

如果Finalize或对Finalize的重写引发异常,则运行时将忽略该异常,终止该Finalize方法,并继续完成过程


有人想知道吗?

这个问题从来没有彻底解决过,但我最终还是通过创建自己的LazyInitializer实现实现了一个相当基本的解决方案,在这里,我在调用时检查Finalize方法,如下所示:

/// <summary>
/// Invoke the actual Property/Method using the Proxy or instantiate the actual
/// object and use it when the Proxy can't handle the method. 
/// </summary>
/// <param name="invocation">The <see cref="IInvocation"/> from the generated Castle.DynamicProxy.</param>
public virtual void Intercept(IInvocation invocation)
{
  try
  {
    if (invocation.Method.Name == "Finalize")
    {
      return;
    }
    if (_constructed)
    {
      // let the generic LazyInitializer figure out if this can be handled
      // with the proxy or if the real class needs to be initialized
      invocation.ReturnValue = base.Invoke(invocation.Method, invocation.Arguments, invocation.Proxy);

      // the base LazyInitializer could not handle it so we need to Invoke
      // the method/property against the real class
      if (invocation.ReturnValue == InvokeImplementation)
      {
        invocation.ReturnValue = invocation.Method.Invoke(GetImplementation(), invocation.Arguments);
        return;
      }
      else
      {
        return;
      }
    }
    else
    {
      // TODO: Find out equivalent to CGLIB's 'method.invokeSuper'.
      return;
    }
  }
  catch (TargetInvocationException tie)
  {
    // Propagate the inner exception so that the proxy throws the same exception as
    // the real object would 
    Exception_InternalPreserveStackTrace.Invoke(tie.InnerException, new Object[] { });
    throw tie.InnerException;
  }
}
//
///使用代理调用实际属性/方法或实例化实际
///对象,并在代理无法处理该方法时使用它。
/// 
///来自生成的Castle.DynamicProxy的。
公共虚拟无效拦截(IInvocation调用)
{
尝试
{
if(invocation.Method.Name==“Finalize”)
{
返回;
}
如果(_构造)
{
//让通用懒散初始值设定项确定这是否可以处理
//如果需要初始化实际类,则使用代理
invocation.ReturnValue=base.Invoke(invocation.Method、invocation.Arguments、invocation.Proxy);
//基LazyInitializer无法处理它,因此我们需要调用
//针对实类的方法/属性
if(invocation.ReturnValue==InvokeImplementation)
{
invocation.ReturnValue=invocation.Method.Invoke(GetImplementation(),invocation.Arguments);
返回;
}
其他的
{
返回;
}
}
其他的
{
//TODO:找出与CGLIB的“method.invokeSuper”等效的方法。
返回;
}
}
接球(目标球)
{
//传播内部异常,以便代理抛出与内部异常相同的异常
//真正的物体会
异常_InternalPreserveStackTrace.Invoke(tie.InnerException,新对象[]{});
抛出tie.InnerException;
}
}

当我迁移到NHibernate的2.1.2版本时,我遇到了同样的问题。我把城堡换成了林府的代理,一切都很顺利。希望这有帮助。

我不确定DynamicProxy是否应该覆盖
Finalize
方法。。。第一位