我有一个方法只有在满足某个条件时才可访问,如果不满足,那么该方法将不会被执行。目前,这是我编码的方式:
public void CanAccessDatabase()
{
if(StaticClass.IsEligible())
{
return;
}
// do the logic
}
现在,这段代码很丑陋,因为没有这个if(StaticClass.IsEligible())
条件与方法的关注点无关。
所以我在考虑将IsEligible
方法放在属性中,以便我的代码看起来像这样。 如果条件未满足,则此方法将返回而不执行以下逻辑。
[IsEligibleCheck]
public void CanAccessDatabase()
{
// do the logic
}
当然,资格是运行时决定。
关于如何为IsEligibleCheck
编写逻辑代码的任何想法?感谢
编辑:我知道PostSharp可以做到这一点,但我正在寻找一些开箱即用的东西,而不是依赖于任何第三方库。
答案 0 :(得分:3)
关于如何为
IsEligibleCheck
编写逻辑代码的任何想法?
这是AOP的理想选择。
编辑:我知道PostSharp可以做到这一点,但我正在寻找一些开箱即用的东西,而不是依赖于任何第三方库。
微软是否被视为第三方?如果没有,您可以从Unity查看Patterns & Practices team。查看Unity中的Interceptor
机制。
否则,您实际上必须使用反射来滚动自己的实现。实际上,您需要做的是将对象包装在代理中,其中代理使用反射来检查属性并适当地解释它们。如果IsEligibleCheck
成功,则代理将调用包装对象上的方法。实际上,重用已经存在的实现更容易。
我的建议是使用Unity(或其他AOP解决方案)。
答案 1 :(得分:2)
这看起来像AOP的完美候选人。简而言之,这意味着CanAccessDatabase
逻辑将存在于“方面”或“拦截器”中,即与业务逻辑分离,从而实现separation of concerns(方面只负责安全性,业务代码只负责业务事务。)
在C#中,执行AOP的两个常用选项是Castle.DynamicProxy和PostSharp。每个都有其优点和缺点。 This question总结了他们的分歧。
Here are other options在.Net中执行AOP,其中一些可以在没有第三方库的情况下完成。我仍然建议使用DynamicProxy,PostSharp,LinFu,Spring.AOP或Unity,其他解决方案也不是那么灵活。
答案 2 :(得分:2)
自定义属性与Reflection相辅相成。
您需要创建另一个负责调用CanAccessDatabase()类中方法的类。
使用反射,这个新类将确定每个方法的属性。如果找到IsEligibleCheck属性,它将执行StatiClass.IsEligible()检查,并且只有在检查通过时才调用CanAccessDatabase()。
继承人an introduction在MSDN上这样做。它围绕使用MemberInfo.GetCustomAttributes()方法。
下面是伪代码:
Get the Type of the CanAccessDatabase() class
Using this type, get all methods in this class (optionally filtering public, private etc).
Loop through the list of methods
Call GetCustomAttributes() on the current method.
Loop through the list of custom attributes
If the IsEligibleCheck attribute is found
If StaticClass.IsEligible is true
Call the current method (using MethodInfo.Invoke())
End If
End If
End Loop
End Loop
答案 3 :(得分:2)
不幸的是,属性不会在运行时执行。少数内置属性修改了编译的代码,如MethodImpl属性等,但所有自定义属性都只是元数据。如果没有代码在寻找元数据,那么它就会坐在那里而不会影响程序的执行。
换句话说,你需要if语句某处。
除非您可以使用PostSharp之类的工具,否则无法在没有明确检查属性的情况下在开箱即用的.NET中完成此操作。
答案 4 :(得分:1)
我知道这是一个老话题......
您可以使用条件属性:http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx
“表示编译器应忽略方法调用或属性,除非定义了指定的条件编译符号。”
#define IsEligibleCheck // or define elsewhere
[Conditional("IsEligibleCheck")]
public void CanAccessDatabase()
{
// do the logic
}
答案 5 :(得分:0)
检查AOP,它将为您提供很多帮助,市场上的一个强大组件是PostSharp