打破了PostSharp 3.0中IAspectProvider的更改

本文关键字:IAspectProvider PostSharp | 更新日期: 2023-09-27 18:28:19

今天我升级到PostSharp 3。在我的项目中引用了正确的DLL之后,我进行了编译,一切似乎都很好,直到我得到一个运行时异常。PostSharp 2.1中一直运行良好的一个方面现在表现不同。

它是在IAspectProvider的帮助下应用的一个通用方面。完整的源代码可以在GitHub上找到。

public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
{
    Type targetType = (Type)targetElement;
    Type genericAspect = typeof( ViewModelAspect<,> ).MakeGenericType( _propertiesEnumType, _commandsEnumType );
    yield return new AspectInstance( targetType, Activator.CreateInstance( genericAspect ) as IAspect );
}

似乎发生的是,具有错误泛型参数的方面应用于我的类型。当我使用dotPeek查看后编译的代码时,我看到了一个新引入的带有泛型参数的泛型字段,这些参数旨在应用于不同的类型事实上,所有应用了方面的类型都共享相同的泛型参数(因此只有一个是正确的)。

这在以前是正确的,是否有任何与PostSharp 3中的IAspectProvider更改有关的事情需要我考虑

出于调试目的,我已经在构建时检查了_propertiesEnumType_commandsEnumType的设置是否正确,而且它们确实正确,因此我认为之后一定出了问题;也许创建的方面应用到了错误的实例?


下面你可以看到PostSharp似乎做错了什么的反编译代码。似乎引入了正确的方面,但我引入的属性暴露为不同的(错误的)类型。注意,ViewModel.Main是方面的参数,而ViewModel.ActivityOverviewCommandFactory的参数,也应该是ViewModel.Main

[NonSerialized]
private ViewModelAspect<Laevo.ViewModel.Main.Binding.Properties, Laevo.ViewModel.Main.Binding.Commands> 'u003C'u003Ez__aspect35;
private CommandFactory<Laevo.ViewModel.ActivityOverview.Binding.Commands> CommandFactory
{
  get
  {
    return ((ViewModelAspect<Laevo.ViewModel.ActivityOverview.Binding.Properties, Laevo.ViewModel.ActivityOverview.Binding.Commands>) this.'u003C'u003Ez__aspect35).CommandFactory;
  }
}

打破了PostSharp 3.0中IAspectProvider的更改

我在新版本中发现了一个bug。NuGet的更新版本修复了这个问题。


在修复程序发布之前,我暂时通过引入非泛型成员来解决这个问题,并在运行时更多地依赖于反射。

[IntroduceMember( Visibility = Visibility.Private )]
//public CommandFactory<TCommands> CommandFactory
public object CommandFactory
{
    get { return _commandFactory; }
    private set { _commandFactory = value; }
}

请注意,错误的转换(在这种情况下应该是Laevo.ViewModel.Main)仍然由PostSharp:生成

private object CommandFactory
{
  get
  {
    return ((ViewModelAspect<Laevo.ViewModel.ActivityOverview.Binding.Properties, Laevo.ViewModel.ActivityOverview.Binding.Commands>) this.'u003C'u003Ez__aspect35).CommandFactory;
  }
}

但是,由于创建了正确的泛型方面,因此我可以在运行时强制转换为正确的类型。一切正常。。。代码变得更加混乱(可能由于更多地依赖反射而变得更慢)。