构造函数注入和默认重载

Bry*_*tts 6 .net c# dependency-injection

让我们说我们有

public interface ITimestampProvider
{
    DateTime GetTimestamp();
}
Run Code Online (Sandbox Code Playgroud)

和一个消耗它的类

public class Timestamped
{
    private ITimestampProvider _timestampProvider

    public Timestamped(ITimestampProvider timestampProvider)
    {
        // arg null check

        _timestampProvider = timestampProvider;
    }

    public DateTime Timestamp { get; private set; }

    public void Stamp()
    {
        this.Timestamp = _timestampProvider.GetTimestamp();
    }
}
Run Code Online (Sandbox Code Playgroud)

和默认实现:

public sealed class SystemTimestampProvider : ITimestampProvider
{
    public DateTime GetTimestamp()
    {
        return DateTime.Now;
    }
}
Run Code Online (Sandbox Code Playgroud)

引入这个构造函数是有帮助的还是有害的?

public Timestamped() : this(new SystemTimestampProvider())
{}
Run Code Online (Sandbox Code Playgroud)

这是一个普遍的问题,即时间戳不是有趣的部分.

Mar*_*ett 7

我认为这取决于场景,并且基本上取决于代码所在的消费者(库与应用程序)以及您是否使用IoC容器.

  • 如果您正在使用IoC容器,并且这不是公共API的一部分,那么让容器执行繁重的工作,并且只使用单个构造函数.添加no-args构造函数只会让事情变得混乱,因为你永远不会使用它.

  • 如果这是公共API的一部分,那么请保留两者.如果您正在使用IoC,请确保您的IoC找到"最贪婪"的构造函数(具有最多参数的构造函数).不使用IoC的人,但使用您的API将不会构建整个依赖图以便使用您的对象.

  • 如果您没有使用IoC容器,但只想使用模拟进行单元测试,请保留no-args构造函数,并使内部的贪婪构造函数.为您的单元测试程序集添加InternalsVisibleTo,以便它可以使用贪婪的构造函数.如果您只是单元测试,那么您不需要额外的公共API表面.