如何使用DI/政府间海洋学委员会的容器的型号的粘合剂ASP.NET 视2+?
题
让我们说有一个用户实体和我将要设置的CreationTime财产的构造DateTime。现在。但作为一个单元的测试采用的我不想要访问的日期时间。现在是直接而是使用ITimeProvider:
public class User {
public User(ITimeProvider timeProvider) {
// ...
this.CreationTime = timeProvider.Now;
}
// .....
}
public interface ITimeProvider {
public DateTime Now { get; }
}
public class TimeProvider : ITimeProvider {
public DateTime Now { get { return DateTime.Now; } }
}
我使用而2在我ASP.NET 视2.0应用程序。我有一个UserController和两创建方法(一个用于获得一个用于员额)。唯一得到的是直线前进,但这一员额不是那么直接的和不那么前进:P因为我需要弄乱的模式粘合剂来告诉它来获取基准的执行情况的ITimeProvider,以便能够建造一个户的实例。
public class UserController : Controller {
[HttpGet]
public ViewResult Create() {
return View();
}
[HttpPost]
public ActionResult Create(User user) {
// ...
}
}
我还想到能够保持所有特点的默认型号的粘合剂。
任何机会来解决这个简单优雅/等?D
解决方案
怎么样,而不是使用一个 ITimeProvider
试试这个:
public class User
{
public Func<DateTime> DateTimeProvider = () => DateTime.Now;
public User()
{
this.CreationTime = DateTimeProvider();
}
}
和你单元试验:
var user = new User();
user.DateTimeProvider = () => new DateTime(2010, 5, 24);
我知道这是不是很优雅而不是搞乱的模式粘合剂,这可能是一个解决方案。如果这个没感觉像一个很好的解决方案可以实现一个定义模式粘合剂和复盖 CreateModel 方法在这里你就会注入的依赖关系的构造模型。
其他提示
一对夫妇的意见:
不注入的依赖关系只是为了查询它们的构造
没有任何理由要注射一个ITimeProvider入用户只需要调用 Now
立即执行。只是注入的创建时间,而不是直接:
public User(DateTime creationTime)
{
this.CreationTime = creationTime;
}
一个很好的经验法则相关的DI是 构造应该执行有逻辑.
不用DI与ModelBinders
一个ASP.NET 视ModelBinder是一个真正的穷人的地方做DI,特别是因为你不能使用的构造注射。剩下的唯一选择是的 静态服务定位反模式.
一ModelBinder翻译HTTP GET and POST信息,以强类型的对象,但是 从概念上 这些类型不域的对象,但似的 数据传输的对象.
一个更好的解决方案ASP.NET 视为放弃的定ModelBinders完全相反 明确地拥抱 什么你收到从HTTP连接 不你完全领域对象.
你可以有一个简单的查找或映射器来检索的领域对象,在你的控制器:
public ActionResult Create(UserPostModel userPost)
{
User u = this.userRepository.Lookup(userPost);
// ...
}
哪里 this.userRepository
是一种注的依赖。
另一种选择是创建一个不同的类表示用户,但没有持续,但没有创建日期的财产。
甚至如果 CreationDate
是的一个 User
's的不变,它可以nullable在你的视图模型的你可以把它设置较远的下游,在你的控制器或域层。
毕竟,这可能并不重要,但应该创建日期的属性真正代表的时刻 建造一个户的实例, 或将它更适合用它来表示时刻,一个用户提交他们的数据?