gpt4 book ai didi

c# - 从 ViewModel 调用业务逻辑是好的做法吗

转载 作者:太空狗 更新时间:2023-10-29 22:03:33 27 4
gpt4 key购买 nike

我正在处理一个大型 ASP.NET MVC 项目(大约 15 个独立项目)。我们正在使用外观设计模式来调用业务逻辑以及其他项目。

问题:在 MVC 应用程序中,从 ViewModel 调用 Facade 是最佳实践吗?

我正在使用单个外观实例来调用所有函数。我为每个 Action 创建一个 ViewModel,并用 ViewModel 中的数据填充它。这些结果使 ViewModel 变大了,但 Controller Action 变薄了,因为我们现在正在 ViewModel 中进行工作。在 ViewModel 构造函数中,我传递外观实例并从业务逻辑层获取所需内容。

public class MyViewModel
{
private Facade _Facade;
public IEnumerable<SomeModel> Collection { get; set; }
public IEnumerable<SelectListItem> Years { get; set; }
public IEnumerable<SelectListItem> Quarters { get; set; }
public int SelectedYear { get; set; }
public int SelectedQuarter { get; set; }


public BottomUpForecastViewModel(EXFacade facade)
{
this._Facade = facade;
this.Years = GetFinancialYears();
this.Quarters = GetFinancialQuarters();
this.SelectedYear = DateTime.Now.Year;
this.SelectedQuarter = TimePeriods.GetQuarterNoForDate(DateTime.Now);
Collection = GetMonthlyCollection(SelectedYear, SelectedQuarter);// Take data from the _Facade(call facade)

}

}

public class MyController : Controller
{


[AcceptVerbs(HttpVerbs.Get)]
public ActionResult BottomUpForecast()
{

return View(new MyViewModel(facade));
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult BottomUpForecast(MyViewModel model)
{

return View();

}

}

这是好的做法吗?

考虑到我们不需要担心依赖关系,您是否有更好的方法建议?

更新:我发现了一篇关于如何让 Controller “节食”精益的有趣文章: http://lostechies.com/jimmybogard/2013/12/19/put-your-controllers-on-a-diet-posts-and-commands/ **

最佳答案

你的想法是正确的。从 View Model 调用业务逻辑是完全可以接受的。我一直这样做。

不幸的是,您当前的实现与具体类型紧密耦合。您可以使用一点抽象重构:

相反,在您的业务层中,创建一个接口(interface) IEXFacade 以传递绑定(bind)您的对象并传递给您的 ViewModel:

public interface IEXFacade
{
public IEnumerable<SomeModel> GetMonthlyCollection(int SelectedYear, int SelectedQuarter);
public IEnumerable<SelectListItem> GetFinancialYears();
public IEnumerable<SelectListItem> GetFinancialQuarters();
public int getSelectedYear();
public int getSelectedQuarter(DateTime dateTime);
}

您的 EXFacade 定义将类似于:

public class EXFacade : IEXFacade
{
private TimePeriods _timePeriods = new TimePeriods();

public int getSelectedYear()
{
return DateTime.Now.Year;
}

public int getSelectedQuarter (DateTime dateTime)
{
return _timePeriods.GetQuarterNoForDate(dateTime);
}


public IEnumerable<SomeModel> GetMonthlyCollection()
{
....
return MonthlyCollection;
}

public IEnumerable<SelectListItem> GetFinancialYears();
{
....
return MonthlyCollection;
}

public IEnumerable<SelectListItem> GetFinancialQuarters();
{
....
return MonthlyCollection;
}

}

现在您的 View 模型将采用 IEXFacade 并且更能容忍变化

public class MyViewModel
{
MyViewModel(IEXFacade facade)
{
Years = facade.GetFinancialYears();
Quarters = facade.GetFinancialQuarters();
SelectedYear = facade.getSelectedYear();
SelectedQuarter = facade.getSelectedQuarter (DateTime.Now);
Collection = facade.GetMonthlyCollection(SelectedYear, SelectedQuarter);
}


//Keeping the Facade Object seems extraneous (unless I'm missing something)
//private Facade _Facade;
public IEnumerable<SomeModel> Collection { get; set; }
public IEnumerable<SelectListItem> Years { get; set; }
public IEnumerable<SelectListItem> Quarters { get; set; }
public int SelectedYear { get; set; }
public int SelectedQuarter { get; set; }
}

目标是通过传递接口(interface)来消除对 EXFacade 类的特定实现的依赖。现在,您的 EXFacade 方法逻辑可以在不破坏 View 模型的情况下进行更改。只要接口(interface)(属性和签名)保持不变。


结论:

我并不偏向于直接从我的 ViewModel 调用逻辑,而不是从我的 Controller 调用逻辑。但是,它通常更方便,因为它节省了一个步骤。相反,直接注入(inject)模型的逻辑不如将其整合到 Controller 中那么明显。但是关于“胖 Controller ”与“胖模型”的争论是相当公平的,我认为没有哪一方更正确。

更重要的是要了解外观模式旨在成为您的“聊天”逻辑层和表示层之间的接口(interface)。为了抽象和解耦,该模式需要一个接口(interface)。一旦使用接口(interface)抽象 Facade,您就可以使用 NInject 等 IOC 容器进一步解耦,将 Facade 注入(inject)到 Controller 或模型中。

我强烈建议在这样的大型项目中使用依赖注入(inject)模式。

关于c# - 从 ViewModel 调用业务逻辑是好的做法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22979484/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com