属性类如何引用使用它的实例?

时间:2012-03-23 14:54:54

标签: c# aop custom-attributes postsharp

假设我有一个属性类:

public class MyCustomAttribute : Attribute
{
    // do stuff
}

我在类属性上使用此属性:

public class MyModel : BaseModel
{
    [MyCustom]
    public string Name { get; set; }
}

MyCustomAttribute的代码中,有没有办法引用正在使用它的MyModel实例?

最终我只是尝试使用AOP(使用PostSharp)创建属性来跟踪模型何时变脏。因此,如果BaseModel具有IsDirty属性,那么我希望能够使用PostSharp执行类似的操作:

public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect
{
    public override void OnSuccess(MethodExecutionArgs args)
    {
        someReferenceToTheObject.IsDirty = true;
    }
}

我已经尝试将引用传递给属性的构造函数:

public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect
{
    private BaseModel _currentObject { get; set; }

    public TrackDirtyPropertyAttribute(BaseModel currentObject)
    {
        _currentObject = currentObject;
    }

    public override void OnSuccess(MethodExecutionArgs args)
    {
        _currentObject.IsDirty = true;
    }
}

然而,当我使用它时:

[TrackDirtyProperty(this)]
public string Name { get; set; }

它告诉我this在该上下文中不可用。

2 个答案:

答案 0 :(得分:4)

你应该这样做:

public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect 
{ 
    public override void OnSuccess(MethodExecutionArgs args) 
    { 
        ((BaseModel) args.Instance).IsDirty = true; 
    } 
} 

答案 1 :(得分:2)

您的构造函数将无法工作(至少不能使用this),因为属性构造函数参数必须可以在静态上下文中访问。并且默认情况下,您不能简单地访问利用类型的实例 - 这是有道理的,因为这实际上是元数据(应用于定义,而不是实例 - 实例刚刚与它绑在一起)。因此,您可以本机访问类型的属性,但不能访问属性使用的类型的实例。

你可能会通过一些人为的反思等等(我甚至不打算冒险思考这个问题),但是,并不像其他方式那样优雅。

另一方面,对于我来说,将属性的状态存储在属性中是没有意义的 - 这不够持久。进行计算以检索一个值(比如你确实得到了一个实例,并设法运行一些逻辑来确定它是否“脏”并在这个意义上提供'实时'值)是的,但使用它来保持在声明之后应用于它的信息似乎是徒劳的,因为该属性的哪个实例仍然存在?在任何情况下,无论我在说这个时可能完全错过了什么,这就是实例本身的用途。