I am trying to use a combination of Domain Driven Design with Test Driven Development for this application I am building in ASP.NET MVC 3. My archictecture is set up with Repositories, Domain Models, View Models, Controllers and Views. All validation will be handled in the view model. I set up my view model to inherit from "IValidatableObject" so that my validation attributes and my custom validation that i set up in the "Validate" method are both executed when my controller method calls "ModelState.IsValid". The problem I am running into is accessing my repository in the Validate method of my view model. I need to access the repository to check for duplicate records in the database. It seems like the best idea would be to create a property of IRepository type and set that property by passing injecting my repository into the constructor of the view model. For example:
我正在尝试将域驱动设计与测试驱动开发的组合用于我在ASP.NET MVC 3中构建的此应用程序。我的架构设置了存储库,域模型,视图模型,控制器和视图。所有验证都将在视图模型中处理。我设置我的视图模型继承自“IValidatableObject”,以便我的验证属性和我在“验证”方法中设置的自定义验证都在我的控制器方法调用“ModelState.IsValid”时执行。我遇到的问题是在我的视图模型的Validate方法中访问我的存储库。我需要访问存储库以检查数据库中的重复记录。似乎最好的想法是创建一个IRepository类型的属性,并通过将我的存储库注入视图模型的构造函数来设置该属性。例如:
public class UserViewModel : IValidatableObject
{
public UserViewModel(User user, IUserRepository userRepository)
{
FirstName = user.FirstName;
LastName = user.LastName;
UserRepository = userRepository;
UserName = user.UserName;
}
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public IUserRepository UserRepository { get; set; }
public IEnumerable<ValidationResult> Validate()
{
UserCriteria criteria = new UserCriteria { UserName = this.UserName };
IList<User> users = UserRepository.SearchUsers(criteria);
if (users != null && users.count() > 0)
{
yield return new ValidationResult("User with username " + this.UserName + " already exists."
}
}
}
Do you guys think this is a good idea?
你们认为这是个好主意吗?
2 个解决方案
#1
2
It is good enough but if I were you, I would use
这很好,但如果我是你,我会用
...
private readonly Func<IUserRepository> userRepositoryFactory;
...
public IEnumerable<ValidationResult> Validate()
{
UserCriteria criteria = new UserCriteria { UserName = this.UserName };
using(var UserRepository = userRepositoryFactory())
{
IList<User> users = UserRepository.SearchUsers(criteria);
if (users != null && users.count() > 0)
{
yield return new ValidationResult("User with username " + this.UserName + " already exists."
}
}
}
#2
0
You can add Domain Service class to get object match with your criteria and validated at domain service level
您可以添加域服务类以使对象与您的条件匹配,并在域服务级别进行验证
public class PurchaseOrder
{
public string Id { get; private set; }
public string PONumber { get; private set; }
public string Description { get; private set; }
public decimal Total { get; private set; }
public DateTime SubmissionDate { get; private set; }
public ICollection<Invoice> Invoices { get; private set; }
public decimal InvoiceTotal
{
get { return this.Invoices.Select(x => x.Amount).Sum(); }
}
}
public class PurchaseOrderService
{
public PurchaseOrderService(IPurchaseOrderRepository repository)
{
this.repository = repository;
}
readonly IPurchaseOrderRepository repository;
public void CheckPurchasedOrderExsist(string purchaseOrderId)
{
var purchaseOrder = this.repository.Get(purchaseOrderId);
if (purchaseOrder != null)
throw new Exception("PO already exist!");
}
}
#1
2
It is good enough but if I were you, I would use
这很好,但如果我是你,我会用
...
private readonly Func<IUserRepository> userRepositoryFactory;
...
public IEnumerable<ValidationResult> Validate()
{
UserCriteria criteria = new UserCriteria { UserName = this.UserName };
using(var UserRepository = userRepositoryFactory())
{
IList<User> users = UserRepository.SearchUsers(criteria);
if (users != null && users.count() > 0)
{
yield return new ValidationResult("User with username " + this.UserName + " already exists."
}
}
}
#2
0
You can add Domain Service class to get object match with your criteria and validated at domain service level
您可以添加域服务类以使对象与您的条件匹配,并在域服务级别进行验证
public class PurchaseOrder
{
public string Id { get; private set; }
public string PONumber { get; private set; }
public string Description { get; private set; }
public decimal Total { get; private set; }
public DateTime SubmissionDate { get; private set; }
public ICollection<Invoice> Invoices { get; private set; }
public decimal InvoiceTotal
{
get { return this.Invoices.Select(x => x.Amount).Sum(); }
}
}
public class PurchaseOrderService
{
public PurchaseOrderService(IPurchaseOrderRepository repository)
{
this.repository = repository;
}
readonly IPurchaseOrderRepository repository;
public void CheckPurchasedOrderExsist(string purchaseOrderId)
{
var purchaseOrder = this.repository.Get(purchaseOrderId);
if (purchaseOrder != null)
throw new Exception("PO already exist!");
}
}