我正在努力将我们的项目从 .Net 2 升级到 .Net4.5,同时我将尽可能多地推送到 NuGet 并确保版本是最新的。
我在运行其中一项测试时遇到问题
测试类:
public class Person
{
public static int PersonBaseMethodHitCount { get; set; }
public virtual void BaseMethod()
{
PersonBaseMethodHitCount = PersonBaseMethodHitCount + 1;
}
public static int PersonSomeMethodToBeOverriddenHitCount { get; set; }
public virtual void SomeMethodToBeOverridden()
{
PersonSomeMethodToBeOverriddenHitCount = PersonSomeMethodToBeOverriddenHitCount + 1;
}
}
public class Employee : Person
{
public static int EmployeeSomeMethodToBeOverriddenHitCount { get; set; }
public override void SomeMethodToBeOverridden()
{
EmployeeSomeMethodToBeOverriddenHitCount = EmployeeSomeMethodToBeOverriddenHitCount + 1;
}
public static int EmployeeCannotInterceptHitCount { get; set; }
public void CannotIntercept()
{
EmployeeCannotInterceptHitCount = EmployeeCannotInterceptHitCount + 1;
}
public virtual void MethodWithParameter(
[SuppressMessage("a", "b"), InheritedAttribute, Noninherited]string foo)
{
}
}
public class MyInterceptor : IInterceptor
{
public static int HitCount { get; set; }
public void Intercept(IInvocation invocation)
{
HitCount = HitCount + 1;
invocation.Proceed();
}
}
测试(此夹具没有设置):
var container = new WindsorContainer();
container.Register(Component.For<MyInterceptor>().ImplementedBy<MyInterceptor>());
container.Register(
Component
.For<Employee>()
.ImplementedBy<Employee>()
.Interceptors(InterceptorReference.ForType<MyInterceptor>())
.SelectedWith(new DerivedClassMethodsInterceptorSelector()).Anywhere);
container.Register(Classes.FromAssembly(Assembly.GetExecutingAssembly()).Pick().WithService.FirstInterface());
var employee = container.Resolve<Employee>();
Person.PersonBaseMethodHitCount = 0;
Person.PersonSomeMethodToBeOverriddenHitCount = 0;
Employee.EmployeeCannotInterceptHitCount = 0;
Employee.EmployeeSomeMethodToBeOverriddenHitCount = 0;
MyInterceptor.HitCount = 0;
employee.BaseMethod();
Assert.That(Person.PersonBaseMethodHitCount, Is.EqualTo(1));
// The BaseMethod was not overridden in the derived class so the interceptor should not have been called.
Assert.That(MyInterceptor.HitCount, Is.EqualTo(0));
Person.PersonBaseMethodHitCount = 0;
Person.PersonSomeMethodToBeOverriddenHitCount = 0;
Employee.EmployeeCannotInterceptHitCount = 0;
Employee.EmployeeSomeMethodToBeOverriddenHitCount = 0;
MyInterceptor.HitCount = 0;
employee.SomeMethodToBeOverridden();
Assert.That(Person.PersonSomeMethodToBeOverriddenHitCount, Is.EqualTo(0));
Assert.That(Employee.EmployeeSomeMethodToBeOverriddenHitCount, Is.EqualTo(1));
Assert.That(MyInterceptor.HitCount, Is.EqualTo(1)); //The test errors out on this line
Person.PersonBaseMethodHitCount = 0;
Person.PersonSomeMethodToBeOverriddenHitCount = 0;
Employee.EmployeeCannotInterceptHitCount = 0;
Employee.EmployeeSomeMethodToBeOverriddenHitCount = 0;
MyInterceptor.HitCount = 0;
employee.CannotIntercept();
Assert.That(Employee.EmployeeCannotInterceptHitCount, Is.EqualTo(1));
Assert.That(MyInterceptor.HitCount, Is.EqualTo(0));
我添加了一条注释来说明测试失败的地方。
据我所知,问题出在 DerivedClassMethodsInterceptorSelector
选择器:
public class DerivedClassMethodsInterceptorSelector : IInterceptorSelector
{
public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
{
return method.DeclaringType != type ? new IInterceptor[0] : interceptors;
}
}
当它进行类型比较时,类型变量是 System.RuntimeType 但应该是 Employee (至少这是我的理解)。
编辑: 这个问题是使用 Castle.Windsor 和 Castle.Core 3.2.1 发生的,在 NuGet 安装 3.1.0 包后,代码按预期工作。
我倾向于这是一个错误,但我也可能只是逻辑上的改变。