静态方法的依赖注入

Bob*_*obr 6 c# asp.net-mvc dependency-injection

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

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

Fre*_*ver 13

如果我理解正确,您希望将ILogger的实例注入静态方法.正如您可能已经想到的那样,当依赖方法是静态时,您无法使用依赖注入"正常方式".

您可能在这里寻找的是服务定位器模式.

使用StructureMap IoC容器(但你真的可以使用任何容器),连接它的配置可能如下所示:

For<ILogger>().Use<SomeLoggerImplementation>();
Run Code Online (Sandbox Code Playgroud)

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

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想指出,这可以被认为是一种反模式,只应在有明确理由的情况下使用,而不仅仅是出于方便.

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

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

如果您不熟悉依赖注入的概念,此链接可以帮助您入门.那里有很多信息.

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

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

public interface IValidateDataInAPI
{
    bool IsValid(string data);
}
Run Code Online (Sandbox Code Playgroud)

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

话虽如此,如果你真的需要保持你的IsValid方法静态,服务定位器模式可能是要走的路.

  • 有哪些很好的例子可以说明解决静态类中的依赖关系的有效场景? (2认同)