c# - 服务的 ASP.NET MVC 设计模式最佳实践

标签 c# asp.net-mvc asp.net-mvc-3

我有一个 ASP.NET MVC 3 应用程序。

我有一个ModelViewModelViewController

我使用 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 示例:

包含从 CustomerCustomerWithOrdersModel 的映射的 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);
}

如果您创建从 CustomerWithOrdersModelCustomer 的映射,您可以使用 customerWithOrdersModel.ToEntity() 将其映射回域模型.

就是这样!您可以从 ViewModel 中删除具有 Customer 域模型的构造函数。

关于c# - 服务的 ASP.NET MVC 设计模式最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17530555/

相关文章:

c# - 将 JSON 对象反序列化为 C# 对象

javascript - 如何从 View 中删除特定 CSS 文件的引用

asp.net-mvc - 删除一行后刷新Jquery数据表

jquery - 使用 ValidationAttribute 的自定义验证不会触发客户端验证

visual-studio-2010 - Visual Studios 2010 SP1 "Unable to copy file ' ...\.svn\all-wcprops' 访问路径 'bin\\.svn\all-wcprops' 被拒绝”

c# - 如果大于 6 个月,则从 SQL Server 中选择记录

javascript - 将数据从 View 中的动态文本框发送到 AngularJS Controller

c# - 将 XML 反序列化为对象数组或单个对象

c# - 用最近 5 年填充选择列表

c# - 是否可以在 My Sql 数据库中保存文件指针?