我正在尝试做一些我认为应该直截了当且容易做的事情,但对于我的生活,我无法让它发挥作用。使用PostSharp,我想创建一个应用于类(或接口)定义的方面,并且该方面在编译时反映它已应用的类型,然后将该反射信息存储在变量中以备提取运行时间。
我知道CompileTimeInitialize函数应该用于生成反射信息并将其保存到变量中。这一切都被序列化了。但是,我无法在运行时获取存储的信息。 RuntimeInitialize可以看到变量及其中的数据,但是当我使用GetCustomAttributes从我的代码中的其他类型获取属性时,该属性为空。
以下是我目前的一些代码:
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Class, AllowMultiple = false, PersistMetaData = true)]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class MetadataAttribute : TypeLevelAspect {
public MetadataAttribute() { }
private int test;
public override bool CompileTimeValidate(Type type) {
this.test = 11;
return true;
}
public override void CompileTimeInitialize(Type type, AspectInfo aspectInfo) {
this.test = 9;
}
public override void RuntimeInitialize(Type type) {
// When I break here, I can see during debugging, that test is 11 (I would have expected 9 to be honest, but I suspect that CompileTimeInitialize is not executed for a TypeLevelAspect - unless I am mistaken?)
}
}
以下是我尝试使用的控制台应用程序来提取数字:
class Program {
static void Main(string[] args) {
var ma = typeof(Test).GetCustomAttribute<MetadataAttribute>();
var test = new Test();
var ma2 = test.GetType().GetCustomAttribute<MetadataAttribute>();
// When I break here, both ma and ma2 have test set to 0.
}
}
[Metadata]
public class Test { }
在此先感谢您的帮助,我们非常感谢并且让我的头发在我的头上比在我的头上更持久:)
答案 0 :(得分:1)
当您使用Type.GetCustomAttributes
时,您需要CLR根据存储在元数据中的定义构建自定义属性的新实例,即通过调用构造函数并设置字段和属性。因此,您没有获得PostSharp创建和初始化的实例,而是一个全新的实例。
如果要访问PostSharp实例,则应使用RuntimeInitialize
将此实例存储在某种方面实例的共享存储库中,然后从代码中访问它们。请注意,PostSharp会懒惰地运行RuntimeInitialize
,因此在初始化之前您将无法访问该实例。