背景
我喜欢Jeffrey Palermo 的洋葱架构模型(类似于Hexagonal Architecture),它规定域模型位于“中心”,基础设施的具体实现,特别是具体存储库位于外围。
所以说我有一个领域模型:
//https://libphonenumber.codeplex.com/
using libphonenumber;
namespace MyApplication.Domain
{
public class Speaker
{
public virtual string Name {get;set;}
public virtual PhoneNumber PhoneNumber {get;set;}
}
}
现在我需要将此领域模型公开给其他团队:
- UI 团队假设想要添加几个数据验证属性和自定义 JSON 序列化属性。
- 基础架构团队假设想要添加 XML 序列化属性和来自 3rd 方数据库实现的一些自定义属性。
- 公共 API 团队假设想要添加 WCF 属性。
我不想让每个团队全权委托将他们的属性添加到我的域模型中 ,我特别不希望他们将所有“特定于层”的依赖项添加到我的模型程序集中。
而且这种情况变得更加复杂,因为我自己使用了第 3 方“域模型”(在这种情况下,使用 Google 的LibPhoneNumber来处理电话号码)。
理想情况下,他们每个人都需要创建自己的包装类,例如:
using MyApplication.Domain;
namespace MyApplication.UI.DomainWrappers
{
public class UISpeaker
{
private Speaker _speaker;
public class UISpeaker(Speaker speaker = null)
{
_speaker = speaker ?? new Speaker();
}
[Required]
public virtual string Name {
get{ return _speaker.Name; }
set{ _speaker.Name = value; }
}
[Required]
public virtual PhoneNumber PhoneNumber {
get{ return _speaker.PhoneNumber ; }
set{ _speaker.PhoneNumber = value; }
}
//Conversion operators
public static implicit operator UISpeaker(Speaker s)
{
return new UISpeaker(s);
}
public static implicit operator Speaker(UISpeaker s)
{
return s._speaker;
}
}
}
问题
编写和维护UISpeaker
类是一件痛苦的事,而且是无聊的样板代码。
有没有更好的方法来添加每个团队想要添加的属性而不让他们直接编辑域模型?或者是否有一些工具可以帮助生成这些包装类(我在想可能是像Fody或T4 Templates这样的编织工具,但我对这两种工具都不太熟悉,不知道它们是否可以在这个用例中提供帮助)。
研究
我环顾 Stackoverflow 并发现了一些类似的问题,但没有一个问题能达到我正在寻找的全部范围:
避免在域模型中使用 JsonIgnore 属性- 结论是仅在域模型上使用 .NET 本机属性,因此您不必依赖 Json.Net
将属性添加到另一个程序集的类- 讨论
CustomReflectionContext
用于将属性添加到现有类型。这看起来真的很酷,但不幸的是,该模型将被移交给第 3 方代码(ORM、EF、Json.Net 等)进行反射,所以我认为这不会在这里工作。在 DDD 中拥有单独的域模型和持久性模型- 确认每一层都应该有自己的域模型版本,但没有讨论是否有任何工具/策略可以使编写/维护该代码更容易。