网络服务 – 一致地使用“现在”的价值通过交易

我正在寻找在整个交易中使用当前日期和时间的一致值的指南。

通过事务我宽松地意味着应用程序服务方法,这种方法通常执行单个SQL事务,至少在我的应用程序中。

环境背景

this question的答案中描述的一种方法是将当前日期放在环境条件下,例如。 DateTimeProvider,并使用它而不是DateTime.UtcNow无处不在。

然而,这种方法的目的只是使设计单元可测试,而我也想防止由于不必要的多次查询引起的DateTime.UtcNow引起的错误,其中一个例子是:

// In an entity constructor:
this.CreatedAt = DateTime.UtcNow;
this.ModifiedAt = DateTime.UtcNow;

此代码创建一个具有稍微不同的创建和修改日期的实体,而有人希望这些属性在创建实体之后是相等的。

另外,环境上下文很难在Web应用程序中正确实现,所以我提出了一种替代方法:

方法注入确定时间提供程序

> DeterministicTimeProvider类被注册为“每个生命周期范围的实例”AKA“实例每个HTTP请求在Web应用程序”依赖。
>它是构造函数注入应用程序服务,并传递给实体的构造函数和方法。
>使用IDateTimeProvider.UtcNow方法来代替通常的DateTime.UtcNow / DateTimeOffset.UtcNow来处理当前的日期和时间。

这是实现:

/// <summary>
/// Provides the current date and time.
/// The provided value is fixed when it is requested for the first time.
/// </summary>
public class DeterministicTimeProvider: IDateTimeProvider
{
    private readonly Lazy<DateTimeOffset> _lazyUtcNow =
        new Lazy<DateTimeOffset>(() => DateTimeOffset.UtcNow);

    /// <summary>
    /// Gets the current date and time in the UTC time zone.
    /// </summary>
    public DateTimeOffset UtcNow => _lazyUtcNow.Value;
}

这是一个好办法吗?有什么缺点?有更好的选择吗?

嗯..这感觉像StackOverflowStackOverflow更好的问题,但肯定 – 我会咬。

Is this a good approach?

如果正确使用,在您描述的场景中,这种方法是合理的。实现了两个目标:

使你的代码更加可测试这是一个常见的模式,我称之为“模拟时钟”,并在许多精心设计的应用程序中找到。
>将时间锁定到单个值。这不常见,但您的代码确实实现了这一目标。

What are the disadvantages?

>由于您正在为每个请求创建另一个新对象,因此将为垃圾收集器创建一个温和的额外内存使用量和额外的工作。这有点像一个微不足道的地方,因为这通常是针对包含控制器的每个请求生命周期的所有对象。
>在加载对象之前进行的额外工作以及进行延迟加载时,从时钟读取之前,还有一小部分时间被添加。这可以忽略不计,但可能在几毫秒的数量级。
>由于该值被锁定,所以您(或使用您的代码的其他开发人员)总是有可能通过忘记在下次请求之前该值不会改变的方式引入一个微妙的错误。您可能会考虑不同的命名约定。例如,而不是“now”,称之为“requestRecievedTime”或类似的东西。
>类似于上一个项目,您的提供商也可能加载错误的生命周期的风险。您可以在新项目中使用它,并忘记设置实例,将其加载为单例。然后锁定所有请求的值。执行这个没有多少可以做,所以一定要很好的评论。 < summary>标签是个好地方。
>您可能会发现,在不可能执行构造函数注入的情况下,您需要使用当前时间,例如静态方法。您将不得不重构使用实例方法,或者必须将时间或时间提供者作为参数传递到静态方法中。

Are there better alternatives?

是的,见Mike’s answer

您也可以通过IClock接口以及SystemClock和FakeClock实现来考虑内置类似概念的Noda Time。然而,这两个实现都被设计为单例。它们帮助测试,但是它们没有实现您的第二个目标,即将每个请求的时间锁定为单个值。你可以随时写一个这样做的实现。

http://stackoverflow.com/questions/32751702/consistently-using-the-value-of-now-througout-the-transaction

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:网络服务 – 一致地使用“现在”的价值通过交易