假设我们拥有受CQRS启发的架构,其中包括命令,域模型,域事件,读取模型DTO等组件.
当然,我们可以在域模型中使用值对象.我的问题是,它们是否也应用于:
我没有看到任何在上述组件中使用Value Objects(VO)的示例.相反,使用原始类型.也许这只是简单的例子.毕竟,我对DDD中使用VO的理解是它们可以作为整个应用程序的粘合剂.
我的动机:
命令.
假设用户提交包含地址字段的表单.我们有Address Value Object来表示这个概念.在客户端构造命令时,我们应该验证用户输入,当它格式正确时,我们可以在那里创建Address对象并用它初始化Command.我认为不需要将Address对象的创建委托给命令处理程序.
域事件.
域模型已经在值对象方面运行,因此通过使用VO发布事件而不是将它们转换为基本类型,我们可以避免使用某些映射代码.我很确定在这种情况下使用VO是可以的.
DTO的.
如果我们的查询端DTO可以包含值对象,则可以提供更多灵活性.例如,如果我们有Money对象,我们可以选择是以EUR还是USD显示,不需要更改Read Model.
我有一个标准的Domain Layer实体:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
它具有某种验证属性:
public class Product
{
public int Id { get; set; }
[NotEmpty, NotShorterThan10Characters, NotLongerThan100Characters]
public string Name { get; set; }
[NotLessThan0]
public decimal Price { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我已经完全弥补了这些属性.这里使用的验证框架(NHibernate Validator,DataAnnotations,ValidationApplicationBlock,Castle Validator等)并不重要.
在我的客户端层,我也有一个标准设置,我不使用域实体本身,而是将它们映射到我的视图层使用的ViewModels(aka DTO):
public class ProductViewModel
{
public int Id { get; set; }
public string Name { get; set; } …Run Code Online (Sandbox Code Playgroud) 我们正在使用AngularJS,C#,ASP.Net Web API和Fluent NHibernate构建Web应用程序.我们决定使用DTO将数据传输到表示层(角度视图).我对DTO的一般结构和命名有些怀疑.这是一个例子来说明我的场景.假设我有一个名为Customer的域名实体,它看起来像:
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Address Address { get; set; }
public virtual ICollection<Account> Accounts { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,在我的视图/表示层中,我需要检索不同类型的Customer,如:
1)Id Id和Name 2)Id,Name和Address 3)Id,Name,Address和Accounts
我创建了一组DTO来实现这个目标:
public class CustomerEntry
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CustomerWithAddress : CustomerEntry
{
public AddressDetails Address { get; set; }
} …Run Code Online (Sandbox Code Playgroud) 我正在MVC REST用Spring Boot和编写一个应用程序Hibernate。我决定DTO使用MAPSTRUCT. 看来我按照指南做了一切,但出现了错误。有什么问题,我无法理解。论坛和google上的信息很少。
PS 起初我以为问题出在Lombok,所以我删除Lombok并手动分配getters / setters。然后问题并没有解决。我在Drink课堂上和DrinkDTO我规定的课程中都参加了getters / setters。但这仍然没有帮助。
喝:
@Entity
@Table(name = "drink", schema = "public")
public class Drink {
public Drink() { // Constructor for Hibernate
}
// Fields
//
private @Id
@GeneratedValue
Long id;
@Column(name = "name")
private String name;
@Column(name = "price")
private float price;
@Column(name = "about")
private String about;
@Column(name = …Run Code Online (Sandbox Code Playgroud) 在具有域层(DL)/业务(服务)层(BL)/表示层(PL)的多层项目中,将实体传递到表示层的最佳方法是什么?
DO => Domain Object;
DTO = Domain Transfer Object;
VM => View Model;
V => View;
Run Code Online (Sandbox Code Playgroud)
选项1:
DL => DO => BL => DTO => PL => VM => V
Run Code Online (Sandbox Code Playgroud)
这个选项似乎是最佳实践,但似乎也很重要.
选项2:
DL => DO => BL => DTO => PL => V
Run Code Online (Sandbox Code Playgroud)
这个选项似乎不是很好的练习,但由于DTO与VM几乎完全相同,我们可以将它直接传递给View,实现和保护它不那么痛苦.
这个选项对于多个布局也是可靠的吗,例如,对于移动设备,我可能需要来自BL的较少信息,因此我需要为这个特定布局使用不同的VM?
我有这些数据传输对象:
public class Report
{
public int Id { get; set; }
public int ProjectId { get; set; }
//and so on for many, many properties.
}
Run Code Online (Sandbox Code Playgroud)
我不想写
public bool areEqual(Report a, Report b)
{
if (a.Id != b.Id) return false;
if (a.ProjectId != b.ProjectId) return false;
//Repeat ad nauseum
return true;
}
Run Code Online (Sandbox Code Playgroud)
有没有更快的方法来测试两个只有属性的对象是否具有相同的值(每个属性不需要一行代码或一个逻辑表达式?)
切换到结构不是一种选择.
我最近开始阅读Evans的Domain-Driven设计书,并开始了一个小样本项目,以获得DDD的一些经验.同时我想了解更多关于MongoDB的知识,并开始用MongoDB和最新的官方C#驱动程序替换我的SQL EF4存储库.现在这个问题是关于MongoDB映射的.我看到用公共getter和setter映射简单对象非常容易 - 没有痛苦.但是我在没有公共设置者的情况下映射域实体有困难.据我所知,构建有效实体的唯一真正干净的方法是将所需的参数传递给构造函数.请考虑以下示例:
public class Transport : IEntity<Transport>
{
private readonly TransportID transportID;
private readonly PersonCapacity personCapacity;
public Transport(TransportID transportID,PersonCapacity personCapacity)
{
Validate.NotNull(personCapacity, "personCapacity is required");
Validate.NotNull(transportID, "transportID is required");
this.transportID = transportID;
this.personCapacity = personCapacity;
}
public virtual PersonCapacity PersonCapacity
{
get { return personCapacity; }
}
public virtual TransportID TransportID
{
get { return transportID; }
}
}
public class TransportID:IValueObject<TransportID>
{
private readonly string number;
#region Constr
public TransportID(string number)
{
Validate.NotNull(number);
this.number = number;
} …Run Code Online (Sandbox Code Playgroud) 我有一个存储库层负责我的数据访问,由服务层调用.服务层返回序列化并通过线路发送的DTO.通常,服务只是访问存储库并返回存储库返回的内容.
但要使其工作,存储库必须返回该DTO的实例.否则,您首先必须将存储库返回的数据层对象映射到服务层中的DTO并返回该对象.这看起来很浪费.
最重要的是,如果DTO的创建发生在服务层中,那么在一个存储库调用之前可能已经完成的事情以及因此一个数据库查询现在必须在服务层中的多个存储库调用发生以"组合"最终的DTO.当然,除非我在数据和服务层之间创建一个可以包含这样一个组合对象的传输对象.这则必须映射到DTO.为了纯洁,这似乎是浪费.但是,让存储库层返回仅通过线路发送的对象也是错误的.
我在具有数据传输对象 (DTO) 类的项目中激活了此功能,如下所示:
public class Connection
{
public string ServiceUrl { get; set; }
public string? UserName { get; set; }
public string? Password { get; set; }
//... others
}
Run Code Online (Sandbox Code Playgroud)
但我收到错误:
CS8618:不可为空的属性“ServiceUrl”未初始化。考虑将该属性声明为可为空的。
这是一个 DTO 类,所以我没有初始化属性。这将是初始化类的代码的责任,以确保属性不为空。
例如,调用者可以这样做:
var connection = new Connection
{
ServiceUrl=some_value,
//...
}
Run Code Online (Sandbox Code Playgroud)
我的问题:当启用 C#8 的可空性上下文时,如何处理 DTO 类中的此类错误?
我正在使用EF 4和POCO开始一个项目.
向客户端发送数据的最佳做法是什么?我应该发送POCO还是应该有DTO?
在将实体(与上下文断开连接)发送到客户端时,我是否应该注意任何问题?
建议的做法是将POCO发送到客户端层吗?
dto ×10
c# ×6
asp.net-mvc ×2
viewmodel ×2
.net ×1
automapper ×1
c#-8.0 ×1
class ×1
cqrs ×1
equals ×1
java ×1
mapstruct ×1
mongodb ×1
nhibernate ×1
orm ×1
poco ×1
spring-boot ×1
validation ×1