默认的MVC模板使用“@ DateTime.Now.Year”来显示版权年份,但我宁愿在任何地方使用NodaTime。
我目前正在使用Ninject将IClock实例注入到控制器中,这些控制器会执行特定时间或日期。是否有推荐的方法来访问MVC中的“全局IClock”,类似于“DateTime.Now”?我想我可以将IClock注入每个Controller,然后将其传递到每个视图中,但有时可以访问全局内容。
我知道我可以在布局模板中使用SystemClock.Instance ...相反,引用全局的,可测试的IClock会更好。
答案 0 :(得分:4)
您可以使用child action。
首先编写一个控制器,您可以像往常一样使用依赖注入,它将包含子操作:
public class CopyrightController: Controller
{
private readonly IClock clock;
public CopyrightController(IClock clock)
{
this.clock = clock;
}
[ChildActionOnly]
public ActionResult Index()
{
// In this example I am directly passing the IClock instance
// to the partial view as model but in a real application
// you might want to use a view model here
return PartialView(this.clock);
}
}
然后您可以拥有相应的部分视图(~/Views/Copyright/Index.cshtml
):
@model IClock
<div>Copyright ...</div>
最后在你的_Layout中调用这个子动作:
<footer>
@Html.Action("Copyright", "Index")
</footer>
答案 1 :(得分:0)
如果您正在寻找可测试的DateTime.Now
,则可以使用SystemTime.Now()
,详见this post by Ayende Rahien。您可以创建默认为Func<DateTime>
的{{1}},但可以将其设置为测试中的特定日期。它可以节省您引入另一个依赖项这是功能:
DateTime.Now
无论您在何处使用public static class SystemTime
{
public static Func<DateTime> Now = () => DateTime.Now;
}
,都应使用DateTime.Now
。你可以在你的测试中设置它:
SystemTime.Now
如果您对日期的使用有足够的测试覆盖率,则应该捕获使用SystemTime.Now = () => new DateTime(2012, 7, 1).Date;
而不是DateTime.Now
的任何实例