14

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

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

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

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

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

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

4

3 回答 3

3

你可以使用PostSharp,它是面向方面的 .NET 框架,看起来很容易使用

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

于 2012-11-04T00:40:08.103 回答
1

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

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

于 2012-11-04T00:17:08.830 回答
1

你是对的,这听起来很像 AOP。
你所追求的听起来像是编译时编织?即,编译器将属性转换为附加代码。
你可以看看如何实现这个...
通过自定义属性生成附加代码
http://www.cs.columbia.edu/~eaddy/wicca/ &
http://www.sharpcrafters.com/aop.net/ compiletime-weaving
都是指执行此操作的工具和技术。

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

于 2012-11-04T00:31:01.057 回答