【发布时间】:2016-07-13 07:50:51
【问题描述】:
我找到了this question - 这与我正在尝试的非常相似。但是,我的用例有点不同。
我们需要存储业务服务的审计历史记录。但是,我们需要能够在方法调用期间手动调用审计检查点,而不仅仅是之前和之后。
我们在项目中使用 Castle.Core。为此,我计划创建一个名为 AuditContext 的自定义属性,用于我们的服务方法(用于审核业务逻辑等)。我计划使用 Castle DynamicProxy 创建一个日志代理,该代理将基于以下内容创建一个新的上下文对象属性对象中的元数据参数。我想做的是将此对象作为方法参数注入我的方法,但不必在我们创建的每个服务方法上指定AuditContext 参数。
基本上,而不是这样:
[AuditContext(someStaticMetadata)
public BusinessObject BusinessMethod (AuditContext context, ...arguments) {
// ...some logic...
context.checkpoint(someAuditData);
}
我希望能够做到这一点:
[AuditContext(someStaticMetadata)
public BusinessObject BusinessMethod (...arguments) { // We do not have to specify the context object for every business method...
// ...some logic...
context.checkpoint(someAuditData); // ...but the object is still available, as the parameter has been added by the argument.
}
或者,为了做一个更通用的例子,我想这样写:
[ProvidesParam2]
public Object myFunc (param1) { }
...最终得到具有此签名的函数:
public Object myFunc (param1, param2) { }
提炼出来的问题是——C# 属性能否将参数添加到它所装饰的方法中,从而在设计时有效地更改方法的签名?
谢谢!
【问题讨论】:
-
我看到的你所问的问题和你链接的问题的答案之间的唯一区别是
AuditContext需要一些静态元数据,而链接问题中的答案需要一个接口。无论哪种方式,您都必须使用反射来实例化对象。除非您能向我解释您所问的内容与链接的问题有何不同,否则我倾向于投票以重复关闭。 -
@JimMischel 他所做的和我所做的主要区别在于我试图使用属性来更改方法的方法签名。事实上,我提供这个问题只是为了表明它不是重复的。我的用例与他有关,但根本问题不同。请参阅我提供的代码示例。
-
不将
someAuditData作为参数传递的唯一方法是使用反射定位AuditContext属性,然后Activator.CreateInstance实例化它,就像对链接问题的回答说。你不能把它当作一个参数来访问。 -
@JimMischel 如果是这样,那么我将无法在我的函数中访问它 - 对吗?具体来说,我之所以询问参数,是因为我相信我可以使用动态代理在运行时将所需的对象传递给方法。问题是,如果不更改方法签名,我认为这是不可能的。
-
是的,你可以。与其给属性提供静态数据,不如给它一个包含函数引用的对象。该方法使用反射找到属性并对其进行实例化,然后调用该方法。该方法提供审计上下文数据。
标签: c# aop custom-attributes castle-dynamicproxy