我想我已经有了这个问题的答案,但是我尽可能地坚持MVVM,并且学习了很长时间。
我目前正在设置View,ViewModel和Model。我的模型使用实体框架查询数据库。
My View有一堆控件允许用户设置查询的参数(基本上构建一个大的where子句).ViewModel存储通过控件设置的这些选项。
所以我的观点 - 视图模型交互似乎非常有用,我认为它是可以接受的。
我的模型公开了一个函数,它将查询结果作为某种IEnumerable返回。我现在遇到的问题是"搜索条件的数量"我已经设置了用户。我现在有模型功能的 9 参数。我不知道它是否可以接受。至少,它很难看。十分难看。但是这样,我的viewModel只需要保存模型的一个实例,然后只需要知道一个函数及其签名。
我应该在模型中设置属性,然后在视图模型中设置这些属性吗?通过这种方式,单个功能将更加清晰,但视图模型必须更加“清晰”。该模型具有哪些属性。我知道创建一些公共属性并不是一件大事,但我想知道哪个更适合MVVM。我们当前的代码库没有任何关注点。所以我自己就这个。
public IEnumerable<> GetResults(string id, string inputName, DateTime? fromDate,
DateTime? toDate, bool option1, int selectCount, bool exactMatch = true, bool showFailed = false)
{
//QUERY HERE, returns results
}
相关的ViewModel调用:
var queryResults = MyModel.GetResults(id, inputname, FromDate, ToDate, Option1, selectCount, ExactMatch, ShowFailed);
Results = queryResults.ToList();
public string Id {get;set}
public string InputName {get;set}
public DateTime? FromDate {get;set}
public DateTime? ToDate {get;set}
public bool Option1 {get;set}
public int SelectCount {get;set}
public bool ExactMatch {get;set}
public bool ShowFailed {get;set}
public IEnumerable<> GetResults()
{
//Query here, return results
}
相关提议的ViewModel调用:
MyModel.Id = this.Id;
MyModel.InputName = this.InputName;
MyModel.FromDate = this.FromDate;
//...etc (I put the this. to clarify the view model also has those properties).
var results= MyModel.GetResults();
答案 0 :(得分:4)
据我了解,您的用例会因执行Command Query Separation而大喊大叫。关于CQS详细信息,您可以看到我的回答here。既然我们已将此作为我们想法的基础,我们将查看下一步的重构步骤。
看到您的方法签名,我们可以清楚地看到您在这里有批次参数:
public IEnumerable<T> GetResults(string id, string inputName, DateTime? fromDate,
DateTime? toDate, bool option1, int selectCount,
bool exactMatch = true, bool showFailed = false)
现在,如果我们引入parameter object而不是当前的九个参数,那么您的代码将变为如下:
public IEnumerable<T> GetResults(FilterObject filterObject)
看起来好多了吧?现在,示例参数对象只是POCO,如下所示:
public class FilterObject
{
public string id { get; set; }
public string inputName { get; set; }
...
}
分离关注点并摆脱紧密耦合的模型和视图模型。可以找到关于查询的非常好的简要介绍here。我们创建一个示例查询处理程序:
public class GetResultsQueryHandler
: IQueryHandler<FilterObject, YourModel>
{
public GetResultsQueryHandler([pass your needed dependencies here])
{
//set them to local variables
}
public YourModel Handle(FilterObject filterObject)
{
// Logic to call GetResults(filterObject) and return the filled model
}
}
现在,您可以很好地将之前的GetResults()
调用分开,并让您的模型的属性为“已填充”。
我们需要做的最后一件事是如何将模型映射到视图模型实例。那里有一堆对象映射器,一个流行的是AutoMapper。在像您这样的情况下,它可以让您的生活更轻松,您需要做的就是设置地图并致电Mapper.Map()
。
在您的问题中显示的示例中,模型和视图模型属性名称相同,映射定义应该很容易:
public static void Configure()
{
Mapper.CreateMap<YourModel, YourViewModel>();
}
然后,为了获得结果映射视图模型,映射操作可以完成:
var viewModel = Mapper.Map<YourModel, YourViewModel>(model);
model
参数是填充模型。
关于我的AutoMapper示例中显示的静态用例方法的引用:
AutoMapper的4.2.0版本将整个静态配置和映射API标记为过时的
这意味着使用AutoMapper&gt; = v4.2创建配置已更改为:
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<YourModel, YourViewModel>();
});
var mapper = config.CreateMapper();
答案 1 :(得分:3)
我说,&#34;它取决于&#34;,这些参数的联系有多紧密。
它们可以分组,然后最好有多个功能。 例如按时间段,严重性,文本搜索等进行过滤。
当它们明显属于一起时,创建一个类或结构来对它们进行分组并传递一个参数。
考虑其他&#39;消费者&#39;可以/将来会使用您的模型,并根据/
做出决定