3

ASP.NET MVC 3 アプリケーションがあります。

私は、、、を持っModelViewModelViewますController

NinjectIoCとして使用しています。

MyControllerは aを使用してViewModelにデータを渡しますView

Services (concrete および interface 型) を使用して から情報を取得ViewModelし、データベースに対してクエリを実行して操作するようになりました。

同じServiceものをセットアップに使用できますViewModelか? それとも、これはデザイン パターンの粒子に反しているのでしょうか。

ViewModelつまり、Serviceレイヤー内の設定を抽象化できますか?

シナリオ

シナリオは次のとおりです。myModelには other への参照がたくさんあるModelsため、コントローラーで をセットアップするViewModelと冗長になり、Controllerがやりすぎていると感じます。だから私は次のようなことができるようにしたい:

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

SetupViewModel関数は次のServiceProviderようになります。

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

ViewModel作成/編集アクションには 1 を使用します。他では再利用しませんViewModel

4

2 に答える 2

5

サービス レイヤーがドメイン モデルを返して、それをコントローラーの ViewModel にマップします。

このようにして、たとえばデスクトップ ビューやモバイル ビューなど、複数の ViewModel でサービス メソッドを使用できます。

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

ビューモデル:

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

Customera から aへのマッピングを含む AutoMapper プロファイルCustomerWithOrdersModel:

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

CustomerWithOrdersModelからへのマッピングを作成するとCustomer、 を使用customerWithOrdersModel.ToEntity()してそれをドメイン モデルにマッピングし直すことができます。

それでおしまい!CustomerViewModel からドメイン モデルを使用してコンストラクターを削除できます。

于 2013-07-08T17:32:37.357 に答える