静态方法的依赖注入

12

我在一个API中有一个类,其中有一个静态方法,旨在验证并记录详细信息。请问如何注入ILogger接口。

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

3
只需将ILogger实现传递给IsValid方法。这是我能提出的唯一建议,因为我不了解您验证类的整体意图。 - EngineerSpock
依赖注入和命名日志记录器 - Taras Kovalenko
1个回答

23

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

您可能正在寻找的是服务定位器模式

使用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容器,对吧?正确使用依赖注入可以消除这种必要性,并在想要单元测试代码时使生活变得更轻松。

如果您不熟悉依赖注入的概念,此链接 可以帮助您入门。有很多信息可供参考。

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

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);
}

现在您可以模拟验证器类,这将使您更轻松地对API类进行单元测试。

话虽如此,如果您确实需要保持IsValid方法的静态性,则服务定位器模式可能是正确的选择。


2
有哪些好的例子是在静态类中解决依赖关系的有效场景? - Ciaran Gallagher
1
您正在使用扩展方法,当然必须是静态的,来添加自定义配置提供程序。而且需要注入特定的数据库实现。 - KarlZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接