【问题标题】:Using Attributes to Call Methods使用属性调用方法
【发布时间】:2012-10-24 01:23:59
【问题描述】:

我有各种单独的方法,它们都需要执行相同的功能,然后再继续自己的实现。现在我可以在每种方法中实现这些功能,但我想知道是否有办法利用attributes 来做到这一点?作为一个非常简单的示例,所有网络调用都必须检查网络连接。

public void GetPage(string url)
{
   if(IsNetworkConnected())
      ...
   else
      ...           
}

这可行,但我必须为每个使用网络的方法调用IsNetworkConnected 方法并单独处理它。相反,我想这样做

[NetworkCall]
public void GetPage(string url)
{
   ...
}

如果网络不可用,则调用错误方法并忽略GetPage,否则调用GetPage

这听起来很像面向方面的编程,但我不想为几个调用实现一个完整的框架。这更像是一种学习练习而不是实施练习,所以我很好奇如何最好地实施这样的事情。

【问题讨论】:

  • 继承呢?让它们都派生自一个基本的“网络”类或类似的东西。

标签: c# reflection architecture attributes aop


【解决方案1】:

你可以使用PostSharp,它是.NET的面向方面的框架,好像quite easy to use

static void Main(string[] args)
{
    Foo();
}

[IgnoreMethod(IsIgnored=true)]
public static void Foo()
{
    Console.WriteLine("Executing Foo()...");
}

[Serializable]
public class IgnoreMethodAttribute : PostSharp.Aspects.MethodInterceptionAspect
{
    public bool IsIgnored { get; set; }

    public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args)
    {
        if (IsIgnored)
        {
            return;
        }

        base.OnInvoke(args);
    }
}

方法级方面功能在免费版中可用:http://www.sharpcrafters.com/purchase/compare

运行时性能:

由于 PostSharp 是一种编译器技术,大部分昂贵的工作都是在构建时完成的,因此应用程序可以快速启动并快速执行。在生成代码时,PostSharp 假设调用虚拟方法或获取静态字段是一项昂贵的操作。与传闻相反,PostSharp 在运行时不使用 System.Reflection。 http://www.sharpcrafters.com/postsharp/performance

【讨论】:

  • 我认为 PostSharp 效率低下,因为它必须经过一层反射......但它听起来就像它在编译时完成了大部分工作。漂亮、干净的 API。我可能会在我的一些项目中尝试一下。
  • 是的,刚刚在他们的网站上看到:"Contrary to rumor, PostSharp does not use System.Reflection at run time."sharpcrafters.com/postsharp/performance 所以,性能似乎不是问题。
  • 谢谢,我会研究 PostSharp。我不是特别想使用框架,但似乎没有替代方案。
【解决方案2】:

你说得对,这听起来很像 AOP。
你所追求的听起来像是编译时编织? IE。该属性由编译器转换为附加代码。
你可以看看如何实现这个...
Generating additional code through a custom attribute
http://www.cs.columbia.edu/~eaddy/wicca/ &
http://www.sharpcrafters.com/aop.net/compiletime-weaving
都是指执行此操作的工具和技术。

或者您可以使用 AOP 框架。恕我直言,你应该看看 AOP 框架。

【讨论】:

    【解决方案3】:

    我认为您不能仅使用 attributes 执行此操作,因为如果您不主动对它们进行操作,它们不会由运行时执行。一种轻量级的方法是Ninject with Interceptions extension,它是一个框架,但非常薄,而且你可能已经在使用它来进行 DI。

    另一个选项,但涉及更多一点,可以基于MEF,然后您可以在激活期间使用属性并使用它们做一些事情。

    【讨论】:

      猜你喜欢
      • 2012-01-27
      • 2018-09-05
      • 1970-01-01
      • 2011-07-19
      • 2016-09-04
      • 2015-12-03
      • 2011-05-13
      • 2018-10-16
      • 2011-03-14
      相关资源
      最近更新 更多