简体   繁体   English

向强类型列表添加任意属性

[英]Adding arbitrary properties to a strongly typed list

I'm looking for a good way to add arbitrary properties to the objects in a strongly typed list, based on the principle that I shouldn't pass a DataTable from my business layer to my presentation layer. 基于不应该将DataTable从我的业务层传递到表示层的原则,我正在寻找一种向强类型列表中的对象添加任意属性的好方法。

For example, I might have a Category class with the properties CategoryId and Title . 例如,我可能有一个带有类CategoryIdTitleCategory类。 On one page I would like to fetch a list of all categories (ie. List<Category> ) together with the most expensive product in each category. 我希望在一页上获取所有类别的列表(即List<Category> )以及每个类别中最昂贵的产品。

A while ago, I would have just returned a DataTable with some additional columns in it with the product data in, but I'm trying not to do that -- it would be trivial to set up it's not good practice. 不久前,我刚刚返回了一个DataTable,其中包含一些附加列,其中包含了产品数据,但是我尝试不这样做-设置它不是一个好习惯,这很简单。

One option is to add a MostExpensiveProduct property to my Category class, but I might want to display the most recently added product in another case, or the cheapest product, so I'd end up adding a lot of properties to cover all the options. 一种选择是在我的Category类中添加一个MostExpensiveProduct属性,但是在另一种情况下,我可能想显示最近添加的产品,或者显示最便宜的产品,因此我最终要添加很多属性来覆盖所有选项。 This just doesn't feel right to me. 这对我来说感觉不对。

Am I missing a trick here? 我在这里错过了一个把戏吗? What is the best way of doing this? 最好的方法是什么? Or should I just be returning a DataTable to which I can add as many columns as I need and not worry about it? 还是应该只返回一个DataTable,可以向其中添加任意多的列,而不用担心呢?

The issue seems to be you have a lot of different views you'd like to offer the user. 问题似乎是您想为用户提供许多不同的视图。 The options I see are: 我看到的选项是:

  • You could construct separate classes for each view that inherit from the Category class. 您可以为从Category类继承的每个视图构造单独的类。 Code gen would be a good solution here. 代码生成将是一个很好的解决方案。
  • You could store an Attributes property, which has an IDictionary interface, and refer to items by key. 您可以存储具有IDictionary接口的Attributes属性,并按键引用项目。 I'm becoming a fan of this approach. 我正在成为这种方法的粉丝。
  • You could generate a data table only for binding purposes, for these views... or develop a data table like component where you can refer to fields by Key... 您可以仅出于绑定目的,针对这些视图而生成数据表...或开发类似于组件的数据表,在其中可以通过Key引用字段...
  • For fields that you compute (say you store sales tax and net price, and compute gross cost), you could store as a method of the Category object, or as an extension method. 对于您计算的字段(例如,您存储营业税和净价,并计算总成本),可以将其存储为Category对象的方法或扩展方法。

I'm sure there are other options that I haven't thought about... 我确定还有其他我没想到的选择...

HTH. HTH。

You should create a specialized class (a view model) for each view you have containing only the properties you are interested in using in the view. 您应该为每个视图创建一个专门的类(视图模型),只包含您感兴趣的视图中使用的属性。 This may seem like unnecessary duplication for the simplest cases, but pays off in terms of consistency and separation of layers. 对于最简单的情况,这似乎是不必要的重复,但是在一致性和层分离方面会有所作为。 You can construct the view models manually, or if that gets tedious, use an object-object mapping framework like AutoMapper . 您可以手动构建视图模型,或者如果繁琐的话,请使用诸如AutoMapper之类的对象-对象映射框架。

There are several things to consider here IMHO. 恕我直言,这里有几件事情要考虑。 First, it seems that the only reference from Category to Product should be Category.Products, meaning you should never have something like Category.MostExpensiveProdcut etc. As far as your business layer, I would do something like this: 首先,似乎从Category到Product的唯一引用应该是Category.Products,这意味着您永远不应该具有Category.MostExpensiveProdcut之类的东西。至于您的业务层,我将执行以下操作:

From your code behind in the presentation layer: 在表示层后面的代码中:

call CategoryManager.GetCategories(); 调用CategoryManager.GetCategories();
call List<Product>ProductManager.GetMostExpensiveProducts(List<Category>); 调用List <Product> ProductManager.GetMostExpensiveProducts(List <Category>);

Now that you have a list of Categories, and a list of Products (assuming your Product has a reference back to its Category) you have all the necessary information to work with. 现在,您已经有了一个类别列表和一个产品列表(假设您的产品具有对其类别的引用),您就可以使用所有必需的信息。 Using this setup your entities (Category, Product) are not polluted. 使用此设置,您的实体(类别,产品)不会受到污染。

Another thing to consider is introducing a services layer. 要考虑的另一件事是引入服务层。 If you find that you don't want (for whatever reason) to make two calls to the business managers, rather you want to make a single call and get all your information in one shot I would consider introducing a services layer sometimes aka "application facade". 如果您发现不想(由于某种原因)打给业务经理两个电话,而又想打个电话并一次获得所有信息,我会考虑引入服务层,有时也称为“应用程序”正面”。 This facade would be responsible for making the individual calls to the business managers and combining results into one response before shipping it back to the UI layer. 该外观将负责向业务经理进行单独的调用,并将结果组合到一个响应中,然后再将其发送回UI层。 Someone mentioned that that custom object would be a "ViewModel", which is correct but often used in reference to MVC. 有人提到该自定义对象将是“ ViewModel”,这是正确的,但经常用于引用MVC。 Another name for it would be a DTO (Data Transfer Object), which designed for use with service layers/application facade. 它的另一个名称是DTO(数据传输对象),其设计用于服务层/应用程序外观。

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

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