我一次又一次地思考对需要访问某些上下文的 POCO 对象(例如 NH 中的 ISession,IRepository)执行验证的最佳方法。
我仍然可以看到的唯一选择是使用Service Locator,所以我的验证看起来像:
public User : ICanValidate {
public User() {} // We need this constructor (so no context known)
public virtual string Username { get; set; }
public IEnumerable<ValidationError> Validate() {
if (ServiceLocator.GetService<IUserRepository>().FindUserByUsername(Username) != null)
yield return new ValidationError("Username", "User already exists.")
}
}
我已经使用了控制反转和依赖注入,由于许多事实,我真的不喜欢 ServiceLocator:
- 更难维护隐式依赖。
- 更难测试代码。
- 潜在的线程问题。
- 仅对 ServiceLocator 的显式依赖。
- 代码变得更难理解。
- 测试时需要注册ServiceLocator接口。
但另一方面,对于普通的 POCO 对象,我看不到任何其他方法可以在没有 ServiceLocator 且仅使用 IoC/DI 的情况下执行上述验证。
目前我在服务层执行这种验证。因此,每当参与者尝试更改用户名(当然可能是不同的用户名)时,服务都会执行此验证。一个明显的缺点是每个使用用户的服务都必须执行此检查(即使是一次调用)。
所以问题是:有没有办法在上述情况下使用 DI/IoC?
谢谢,
德米特里。