我有一个 ASP.NET MVC 3 应用程序。
我有一个Model
、ViewModel
、View
、Controller
。
我使用 Ninject
作为 IoC。
我的 Controller
使用 ViewModel
将数据传递给 View
。
我已经开始使用 Service
(具体和接口(interface)类型)从 ViewModel
中获取信息并针对数据库进行查询以对其进行操作。
我可以使用相同的 Service
来设置 ViewModel
吗?或者这是否违背了设计模式的原则?
即我可以在 Service
层抽象设置 ViewModel
吗?
场景
场景是;我的 Model
有很多对其他 Model
的引用,所以当我在 Controller 中设置 ViewModel
时,它太冗长了,我觉得 Controller
做得太多了。所以我希望能够做类似的事情:
var vm = _serviceProvider.SetupViewModel(Guid model1Id, Guid model2Id,/*etc..*/)
ServiceProvider
中的 SetupViewModel
函数如下所示:
public MyModelViewModel SetupViewModel(Guid model1Id, Guid model2Id, /*etc...*/)
{
var vm = new MyModelViewModel();
var model1 = _repository.Model1s.FirstOrDefault(x => x.Id.Equals(model1Id));
var model2 = _repository.Model2s.FirstOrDefault(x => x.Id.Equals(model2Id));
// etc....
vm.Model1 = model1;
vm.Model2 = model2;
return vm;
}
通过这样做,我还可以添加一些 null
条件,而不用担心让我的 Controller
真的非常非常大!!
我使用 1 个 ViewModel
进行创建/编辑操作。我不会在别处重用 ViewModel
。
最佳答案
我会让服务层返回一个域模型并将其映射到 Controller 中的 ViewModel。
这样您就可以使用具有多个 ViewModel 的服务方法,例如用于桌面和移动 View 。
你可以让AutoMapper通过在采用域模型的 ViewModel 中创建构造函数,为您完成繁重的工作或手动完成。
领域模型:
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Telephone { get; set; }
public string Email { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
View 模型:
public class CustomerWithOrdersModel
{
public CustomerWithOrdersModel(Customer customer)
{
Id = customer.Id;
FullName = string.Format("{0}, {1}", customer.LastName, customer.FirstName);
Orders = customer.Orders.ToList();
}
public int Id { get; set; }
public string FullName { get; set; }
public IEnumerable<Order> Orders { get; set; }
}
编辑:AutoMapper 示例:
包含从 Customer
到 CustomerWithOrdersModel
的映射的 AutoMapper 配置文件:
public class ViewModelProfile : Profile
{
public override string ProfileName
{
get { return "ViewModel"; }
}
protected override void Configure()
{
CreateMap<Customer, CustomerWithOrdersModel>()
.ForMember(dest => dest.FullName, opt => opt.MapFrom(src => string.Format("{0}, {1}", src.LastName, src.FirstName)))
.ForMember(dest => dest.Orders, opt => opt.MapFrom(src => src.Orders.ToList()));
}
}
Id
按约定映射。
ViewModelProfile
的扩展方法:
public static class ViewModelProfileExtensions
{
public static CustomerWithOrdersModel ToModel(this Customer customer)
{
return Mapper.Map<CustomerWithOrdersModel>(customer);
}
public static Customer ToEntity(this CustomerWithOrdersModel customerWithOrdersModel)
{
return Mapper.Map<Customer>(customerWithOrdersModel);
}
}
Controller Action :
public ActionResult Details(int customerId)
{
Customer customer = _customerService.GetById(customerId);
CustomerWithOrdersModel customerWithOrders = customer.ToModel();
return View(customerWithOrders);
}
如果您创建从 CustomerWithOrdersModel
到 Customer
的映射,您可以使用 customerWithOrdersModel.ToEntity()
将其映射回域模型.
就是这样!您可以从 ViewModel 中删除具有 Customer
域模型的构造函数。
关于c# - 服务的 ASP.NET MVC 设计模式最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17530555/