如何在不丢失单元测试功能的情况下将日志记录添加到静态类?

时间:2018-06-25 15:23:51

标签: c# unit-testing dependency-injection functional-programming

注意::我意识到这个问题与this SO thread类似,但是我在这里询问的是一个具体情况,所以请不要关闭该问题,因为它是该问题的重复项。

我正在尝试使C#更具功能性,并一直在阅读Enrico Buonanno的C#中的函数式编程。他展示的一种技术是Try类,它使您可以优雅地处理异常。您可以看到Tryhere的代码。

这一切都非常整洁,但是在一个真实的应用程序中,我想记录异常。由于他的课程是静态的,所以我看不到任何方法。正如上面链接的SO问题(以及其他问题)所述,注入静态类要么无法完成,要么不是一个好主意。

我唯一看到的选项是:

  1. 与调用静态方法相反,需要使用代码来创建Try类的实例(目前尚无法使用其代码)。这使代码不那么干净

  2. ILogger类添加静态Try属性,并在使用该类之前进行设置。我不想这样做,因为Try类将同时在我的应用程序的客户端和服务器上使用,并且两种情况下的记录器都将有所不同

  3. 向类方法中添加一个ILogger参数。我之所以不喜欢它,原因与1.中的相同。

  4. 访问try类中的依赖项解析器,并获取记录器的实例。这意味着使用Try的代码也将最终记录到文件中,这不是一个好主意。

有人建议吗?这种方法看起来干净利落,但似乎也缺少明显的基本功能。

1 个答案:

答案 0 :(得分:1)

为什么不让静态方法创建该类的实例,然后再调用可完成该工作的私有实例方法?我对Try不熟悉,但是您可以执行以下操作(警告-空代码!)...

public class Try<T> {
  // Assuming NInject, but same applies to any other container
  [Inject]
  ILogger Logger { get; set; }

  private Try() {
    // stops anyone from outside this project from creating an instance of Try
  }

  public static Exceptional<T> Do(Action f) {
    Try<T> t = new Try<T>();
    return t.DoPrivate<T>(f);
  }

  private Exceptional<T> DoPrivate<T>(Action f) {
    // This is an instance method, so has access to the injected logger
    try {
      return f();
    } catch (Exception ex) {
      Logger.Log(ex.Message);
      return ex;
    }
  }
}

有帮助吗?正如我说的,我对他的代码不熟悉,因此您可能需要对其进行一些调整,但是我认为这将为您提供所需的内容。