gpt4 book ai didi

domain-driven-design - 将有界上下文实现到基于 Entity Framework 的基础设施

转载 作者:行者123 更新时间:2023-12-04 00:14:06 24 4
gpt4 key购买 nike

我已经为我们全新的 Intranet 项目创建了一个基础架构,并尝试遵循几乎所有的最佳实践。我还想提一下,这是我第一次从零开始创建架构。

目前我的基础设施的第一个版本已经准备好并且运行良好。但我想在下一个版本中实现有界上下文结构。

我试图在下面解释当前的情况。

数据库核心:负责数据操作。 Entity Framework 5 代码首次使用。只有一个 DbContext 类和其中定义的所有 DbSet。 GenericRepository 模式和 Unit of Work 模式也是基于以下接口(interface)实现的。

IGenericRepository

public interface IGenericRepository<TEntity>
where TEntity : class {
void Delete(object id);
void Delete(TEntity entityToDelete);
System.Collections.Generic.IEnumerable<TEntity> Get(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter = null, Func<System.Linq.IQueryable<TEntity>, System.Linq.IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");
System.Collections.Generic.IEnumerable<TEntity> GetAll();
TEntity GetByID(object id);
System.Collections.Generic.IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters);
void Insert(TEntity entity);
void Update(TEntity entityToUpdate);
}

工作单位
 public interface IUnitOfWork {
void Dispose();
IGenericRepository<Test> TestRepository {
get;
}
IGenericRepository<Log> LogRepository {
get;
}
void Save();
}

型号:负责存储 DbCore 和 Entity Framework 的实体模型
域名:表示业务逻辑层还存储存储在模型项目中的实体对象的 DTO。当前业务逻辑存储在实现以下接口(interface)的服务类中
服务
public interface IService<TEntity> {

IEnumerable<TEntity> Get();
TEntity GetByID(int id);
void Insert(TEntity entity);
}

该服务类通过 ctor 参数获取 UnitOfWork 并用于操作。 Automapper 还实现了将实体对象转换为 DTO,反之亦然。
从现在开始,所有上层不再对实体模型感兴趣,只使用 DTO。所以几乎所有的项目(包括 api 和 web )都引用了这个项目。

常见:负责存储日志等常用库。

网络核心:负责存储 API 或 MVC 等基于 Web 的项目的常用库。还包含基于 MVC 的项目的扩展、处理程序和过滤器。

接口(interface): ASP.Net MVC Web API 项目代表服务层。使用域层并服务于客户端。
Controller 获取 IService 接口(interface)作为 ctor 参数,并使用它通过域层访问数据层。

网址:基于 ASP.Net MVC 4 的 web 项目,负责与用户交互。使用 Api 方法来访问数据。所有 Controller 都有一个名为 IConsumeRepository 的接口(interface),它通过 HttpClient 连接 API。
 public interface IConsumeRepository<TEntity> {
Task<TEntity> Create(TEntity TestInfo);
Task Delete(int id);
Task<IEnumerable<TEntity>> Get();
Task<TEntity> Get(int id);
TEntity New();
Task<TEntity> Update(TEntity TestInfo, int entityId);
}

Autofac 负责所有项目的 IoC 和 DI。

现在这是我当前的基础设施,我想我解释了需要评估的所有内容。

现在我试图弄清楚以下事情,

问题一:有什么东西不能像我使用的那样受到影响吗?

问题二:实现限界上下文的最佳方法是什么?我最近观看了 Julie Lerman 的视频并查看了许多示例项目。我看到从 DbContext 派生 BC 的常见事情。但我不能确定。因为我认为 BC 应该在域(业务逻辑)层而不是 DbCore(数据访问)层。

问题3:正如我上面提到的,我的 Api 和 Web 项目使用 DTO,因此它们都需要引用域层。但我不喜欢它,因为我使用 API 将业务层与 UI 分开,并为实体再次耦合它们。但我找不到比这更好的方法了。

这是一个很长的问题,但如果您与我分享您的想法以创建更好的架构,我将非常高兴。

最佳答案

问题一 :假设您有一个复杂的业务领域和重要的业务逻辑,那么值得付出努力,因为您必须将您的领域层与基础设施问题隔离开来。然而,情况往往并非如此。如果您主要只是将数据从数据库移动到 UI 并再次返回,那么这就是过度工程,您应该寻求移动部件更少的东西。

问题二:你有多少不同的领域模型(使用不同的普遍存在的语言)?一?二?三?对于每个模型,尽可能将其与其他模型和基础设施问题隔离开来。

Eric Evans 将有界上下文定义为主要是语言边界(引自他的书中):

A BOUNDED CONTEXT delimits the applicability of a particular model so that team members have a clear and shared understanding of what has to be consistent and how it relates to other CONTEXTS. Within that CONTEXT, work to keep the model logically unified, but do not worry about applicability outside those bounds. In other CONTEXTS, other models apply, with differences in terminology, in concepts and rules, and in dialects of the UBIQUITOUS LANGUAGE.



DBContext 可能会为您指明正确的方向,但请记住,它是基础设施工件,而不是域概念。它“代表了工作单元和存储库模式的组合,使您能够查询数据库并将更改组合在一起,然后将这些更改作为一个单元写回存储区。”_(来自 MSDN Docs)。

DDD 是关于领域建模:使用模型来解决复杂业务领域中的困难业务问题。从技术考虑中推导出模型边界感觉就像在摇尾部一样。从概念上定义模型的边界,然后相应地调整您的技术基础设施。

问题3: DTO 可能是强制执行上下文边界的好方法,例如对于 API。然后,该 API 可以作为其他模型的反腐败层。人们通常将它们用于 UI 的原因是避免将 UI 概念引入领域模型。

不要寻求完美的架构。并意识到“最佳实践”实际上只是基于特定情况的指导方针。遵循其他更有经验的人制定的指导方针,并了解您的情况可能略有不同。当您发现摩擦时,使用您的期望重构您的设计决策。例如,如果稍后您发现 UI 的 DTO 太过分了,则将其删除。尽可能简化。

关于domain-driven-design - 将有界上下文实现到基于 Entity Framework 的基础设施,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14891640/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com