【发布时间】:2015-08-12 16:12:25
【问题描述】:
也许你们中的一些人已经创建了基于洋葱架构的工作应用程序,并且已经解决了我的问题并愿意分享他们的经验。
这就是困扰我的地方。
假设我有超过 100 列的 DomainModel“客户”。
但是对于一个特定的视图,我只需要first and last name for rows meeting some specific conditions
我正在使用存储库/服务模式来公开一些基本的 CRUD 内容。 示例服务
public class Service<TEntity, TKey> : IService<TEntity, TKey>
where TEntity : BaseEntity<TKey>
where TKey : IComparable
{
public IUnitOfWork UnitOfWork { get; private set; }
private readonly IRepository<TEntity, TKey> _repository;
}
public class CustomerService : Service<Customer,int>, ICustomerService
{
public ???? GetValidCustomer();
}
现在我有 3 个想法如何处理它,但似乎没有一个是好的。
第一个)在控制器中编写查询
var viewModel = _customerRepository().GetAll().Where(...).Select(...).FirstOrDefault();
我不喜欢这个解决方案,因为它将业务逻辑引入控制器操作,这也可能创建可重复的代码。如果条件发生变化,我将不得不查找整个项目中的所有查询才能更改它们。
2nd) 将视图模型移动到 Service layers
由于Web是洋葱架构的最外层,并且依赖于其他内层,因此我无法重用ViewModel并在Service layers中编写这样的方法,因为不允许循环依赖。
public ValidCustomerViewModel GetValidCustomer()
{
return _customerRepository().Where(..).Select(new ValidCustomerViewModel() {....} ).FirstOrDefault();
}
同样在服务层创建 ViewModel 似乎不是合适的地方,因为我认为单个服务方法应该能够操作域而不是为视图创建数据(我认为这是 controller 责任)
public ValidCustomerViewModel GetValidCustomer()
{
var viewModel = new ValidCustomerViewModel();
viewModel.Customer _customerRepository().Where(..).Select(new ValidCustomerViewModel() {....} ).FirstOrDefault();
viewModel.Cats = _catRepository.Where(...).ToList();
} //So bad :(
第三次创建 Dto
创建ont to one ViewModel 和 Dto
Inside -> (XXX.Web.Portal.ViewModels.Customer)
public class ValidCustomerViewModel()
{
[Required]
public string FirstName {get;set;}
[Required]
public string LastName {get;set;}
}
Inside ->(XXX.Core.Dto)
public class ValidCustomerDto
{
public string FirstName {get;set;}
public string LastName {get;set;}
}
public ValidCustomerDto GetValidCustomer()
{
_customerRepository().Where(..).Project().To<ValidCustomerDto>().FirstOrDefault();
}
var dto = _customerServices().GetValidCustomers();
viewModel = Mapper.Map<ValidCustomerModel>(dto);
这会产生一些额外的代码,但它可以修改并且方法返回具体属性。然而,这带来了新的问题...... 现在我可能需要编写类似的方法
public List<ValidCustomerDto> GetValidCustomers()
public PaginatedList<ValidCustomerDto>() GetPaginatedValidCustomersList(...)
第四次返回 IQueryable
public IQuerable<Customer> GetValidCustomer()
{
return _customerRepository.Where(...);
}
var viewModel = _customerServices.GetValidCustomer().Project.To<MaValidCustomerViewModel>().FirstOrDefault();
当我写我的问题时,这个想法出现在我的脑海中:) 好吧,这实际上还不错,我看不出有什么重大缺陷。你觉得呢?
非常欢迎所有建议:)
【问题讨论】:
标签: c# model-view-controller onion-architecture