这不是一个有明确答案的问题,但我需要一些关于我的架构的建议。关于这个话题可能会有很多不同的观点。
我正试图将我的架构从愚蠢的实体转移到丰富的领域对象。在我当前的版本中,我有具有只读属性和表示业务逻辑的方法的抽象域对象:
abstract class Project
{
public string PropertyName { get; protected set; }
public void Setup(SetupData data)
{
...
Save();
}
protected abstract void Save();
}
我从它们派生来实现到持久性实体的映射和实现保存逻辑:
class MongoProject
{
MongoProject(ProjectDocument document, Action<ProjectDocument> save)
{
MapFrom(document);
}
public override Save()
{
MapTo(document);
save(document);
}
}
这很容易工作,项目总是有效的,因为它没有公共setter,它可以被测试,甚至与文档的映射。
但我也意识到一些问题:
- 我总是忘记映射一些属性,没有办法告诉MongoProject它必须序列化什么。
- 有时候实现映射是相对复杂的,因为你不知道保存方法中发生了什么变化,特别是在项目是一个复杂的聚合根的情况下。在我的情况下,很容易实现mongodb的持久性,但它是一个噩梦与实体框架。
如何解决应用程序中的持久性问题,是否有其他解决映射问题的方案?
这是一个有点宽泛的问题。
我从来没有实现我的领域对象和我的数据访问层(保存到db,文件,云等)在同一个类。需要将关注点分开。你的域对象不需要知道如何将自己保存到数据库。
我要做的是在一个类中创建我的域对象,并创建一个单独的数据访问层,它负责将我的数据保存到我想要保存的任何来源。这样,每次你想要保存你的实体到不同的位置,你的对象模型不会在意,你根本不需要改变它。
要将POCO对象映射到DB实体,请使用AutoMapper,它将为您节省大量样板代码,并且您只需要配置一次
例如:// Domain object
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
// Data Access Layer
public class MongoAccessLayer : IDal
{
public void SaveEntity<T>(T entity)
{
// Save logic here
}
public void LoadEntity<T>(T entity)
{
// Load logic here
}
}
// Interface defining what the access layer should look like
public interface IDal
{
void SaveEntity<T>(T entity);
void LoadEntity<T>(T entity);
}