繁体   English   中英

ASP.NET MVC设计模式最佳实践与服务

[英]ASP.NET MVC Design Pattern Best Practice with Services

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

我有一个ModelViewModelViewController

我使用Ninject作为IoC。

我的Controller使用ViewModel将数据传递给View

我已经开始使用Service (具体和接口类型)从ViewModel获取信息并对数据库进行查询以对其进行操作。

我可以使用相同的Service来设置ViewModel吗? 或者这是否违背设计模式?

即我可以抽象在Service层中设置ViewModel吗?

脚本

情景是; 我的Model有很多对其他Models的引用,所以当我在控制器中设置ViewModel时,它是详细的,我觉得Controller做得太多了。 所以我希望能够做到这样的事情:

var vm = _serviceProvider.SetupViewModel(Guid model1Id, Guid model2Id, /*etc..*/)

ServiceProviderSetupViewModel函数如下所示:

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

我会让服务层返回一个域模型并将其映射到控制器中的ViewModel。

这样,您可以使用具有多个ViewModel的服务方法,例如桌面和移动视图。

您可以通过在ViewModel中创建一个采用域模型的构造函数,让AutoMapper为您完成繁重的工作或手动完成。

域名模型:

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; }
}

ViewModel:

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示例:

AutoMapper配置文件,包含从CustomerCustomerWithOrdersModel的映射:

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);
    }
}

控制器动作:

public ActionResult Details(int customerId)
{
    Customer customer = _customerService.GetById(customerId);
    CustomerWithOrdersModel customerWithOrders = customer.ToModel();
    return View(customerWithOrders);
}

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

而已! 您可以从ViewModel中删除具有Customer域模型的构造函数。

如果您将视图模型作为自己的项目并处理服务层中视图模型的映射和返回,我认为没有错。 为了分离关注点,您可以始终拥有另一个处理映射的组件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM