【问题标题】:Dependency injection for a static method [duplicate]静态方法的依赖注入
【发布时间】:2015-06-06 00:25:58
【问题描述】:

我在 API 中有一个类,有一个静态方法,用于验证和记录详细信息。请指导如何注入 ILogger 接口。

public class ValidateDataInAPI
{
    public static bool IsValid(string data)
    {
        //do something
        If(error) 
        {
            _logger.Error("Log error as implemented by caller");
        }
    }
}

【问题讨论】:

  • 只需将 ILogger 实现传递给 IsValid 方法。这是我可以建议的唯一一种方法,因为我不了解您的验证课程的总体意图。
  • [依赖注入和命名记录器][1] [1]:stackoverflow.com/questions/3452318/…

标签: c# asp.net-mvc dependency-injection


【解决方案1】:

如果我理解正确,您想将 ILogger 的实例注入到静态方法中。正如您可能已经发现的那样,当依赖方法是静态的时,您不能以“正常方式”使用依赖注入。

您可能在这里寻找的是service locator pattern

使用 StructureMap IoC 容器(但您实际上可以使用任何容器),用于连接它的配置可能如下所示:

For<ILogger>().Use<SomeLoggerImplementation>();

实施后,您的调用代码可能如下所示:

public class ValidateDataInAPI
{
    private static ILogger Logger
    {
        // DependencyResolver could be any DI container here.
        get { return DependencyResolver.Resolve<ILogger>(); }
    }

    public static bool IsValid(string data)
    {
        //do something
        If(error) 
        {
            Logger.Error("Log error as implemented by caller");
        }
    }
}

我想指出,这可以被认为是一种反模式,并且只应在有明确理由时使用,而不仅仅是为了方便。

依赖注入的整个想法是您将依赖注入到调用代码的构造函数中,从而将类的所有依赖暴露给外部世界。

这不仅提高了代码的可读性(没有内部隐藏的“惊喜”),还提高了可测试性。您不想在您的单元测试项目中配置您的 IoC 容器,是吗?以正确的方式使用依赖注入消除了这种必要性,并在您想要对代码进行单元测试时使您的生活变得更加轻松。

如果您不熟悉依赖注入的概念,this link 可以帮助您入门。那里有很多信息。

使用依赖注入,您的调用代码将如下所示:

public class ValidateDataInAPI : IValidateDataInAPI
{
    private readonly ILogger _logger;

    // Since the dependency on ILogger is now exposed through the class's constructor
    // you can easily create a unit test for this class and inject a mock of ILogger.
    // You will not need to configure your DI container to be able to unit test.
    public ValidateDataInAPI(ILogger logger)
    {
        _logger = logger;
    }

    public bool IsValid(string data)
    {
        //do something
        If(error) 
        {
            _logger.Error("Log error as implemented by caller");
        }
    }
}

同样,通过为验证类定义接口,您可以将该验证类注入 API 类:

public interface IValidateDataInAPI
{
    bool IsValid(string data);
}

您现在可以模拟 Validator 类,这将允许您更轻松地对 API 类进行单元测试。

话虽如此,如果您确实需要将 IsValid 方法保持为静态,那么服务定位器模式可能是可行的方法。

【讨论】:

  • 在解决静态类中的依赖项是有效场景的好例子有哪些?
  • 您正在使用扩展方法(当然必须是静态的)来添加自定义配置提供程序。这需要注入特定的数据库实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多