假设我有一个描述域模型的域程序集,它有一个名为product的类:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
我还有另一个程序集,它是使用此域模型运行的Web应用程序。现在我想创建一个表单来创建新产品并对属性进行一些验证。最简单的方法是在类上使用DataAnnotations。然而,这导致域模型现在包含有关表单验证的元数据,这不是一个非常明确的关注点分离。
该类可能具有MetadataType
属性,但我认为这并不是更好。突然,您的域模型类依赖于表单验证metada类。
另一种方法是创建一个CreateProductForm
类并在那里添加所需的属性,并在类之间进行映射。然而,这会产生一些开销,因为您需要单独维护这些类,并且一个中的更改可能会破坏另一个。在某些情况下可能需要这样做,但在其他情况下,它可能只会创建额外的工作(例如,假设您有一个Address类)。
更新:有些人建议我使用AutoMapper,我已经知道了。 AutoMapper只是使映射更简单,更容易,实际上并没有解决必须维护两个几乎相同的独立类的问题。我的偏好是只在需要时才创建表单类。
是否可以直接在Web程序集中声明注释,而不会为域程序集创建不必要的依赖项?
答案 0 :(得分:3)
如果您不想在域模型和视图之间引入耦合,则应该使用CreateProductForm类方法。
根据您的项目规模/要求,您必须迟早将您的视图模型与您的域分开。假设您正在使用DisplayName属性:您要标记您的域实体吗?
使用像AutoMapper这样的工具可以极大地简化映射过程。
答案 1 :(得分:2)
为什么不在域类上使用DataAnnotations。如果有必要的东西,那么我认为在域中标记它是完全有效的。
其他DataAnnotations,如StringLength,Range等,对我来说完全有效的东西来装饰您的域实体。
实现IValidableObject也是域对象做恕我直言的完全可以接受的事情。
我不会把UI上的内容放在UIHint上,或者说是描述属性格式的annoations。那会很糟糕。
通常我会避免在用户界面上显示域类,并将ViewModel类与AutoMapper等映射工具一起使用以映射到另一个。 ViewModel类具有域类的annoations,可能还有其他UI特定注释。
答案 2 :(得分:0)
作为mathieu和XHalent状态,您应该使用CreateProductForm(或CreateProductFormViewModel)和Automapper,并创建将模型自动化为动作的视图模型的属性。
这样,所有表单验证都会在您的视图模型上进行,所有数据验证(与数据库相关)都会在您的域模型中进行。
在Silverlight和WPF中,它被称为MVVM pattern,许多做asp.net mvc的人推荐它。
在我目前的项目中,我也在使用Automapper。我的所有视图都有一个关联的视图模型,它是特定于该视图的域模型的展平版本。
我认为this是我使用的示例(它仍然是我仍然收藏的那个。但是第一个链接的one似乎更好。) 使用该属性意味着您从控制器中的操作返回域对象,而automap属性会自动将域对象映射到您的viewmodel。
这样做可以为您提供所需的分离。