我一直在阅读洋葱架构,并尝试围绕它构建我的项目。我碰到了一些我不确定的解决方法。我的解决方案按API /基础架构/核心解决方案进行组织。
Core项目保存着我的domain entities
,repository interfaces
,UseCase interfaces
和UseCase implementations
(是否应该将它们移到第4个称为业务层的项目?)
基础结构项目保留了我对存储库的实施,并且DTO负责处理我的所有数据交易。
我的domain models
看起来像这样(尽管在示例中只是随机类)
public class Person {
public int Age {get; set; }
public string Name {get;set;}
}
现在我的基础架构拥有实际的数据层特定实体,其中包括一些额外信息:
public class BaseEntity {
public Guid Id {get;set;}
public DateTime CreatedAt {get;set;}
public DateTime ModifiedAt {get;set;}
}
//This is the devil
public class AppPerson : BaseEntity {
public int Age {get; set; }
public string Name {get;set;}
}
通常,领域模型可以映射到任何内容,以便数据库中的“人员”可以根据业务逻辑实现3种不同类型的用例的模型,但是它们全都是“人员”。数据库。我很高兴在Person
和AppPerson
类之间进行映射。
AppPerson
是我在上下文中定义为DbSet的那个,它已保存到数据库中。
在我的存储库中,我现在想要一个这样的函数:
public async Task<List<AppPerson>> GetGeneric(Expression<Func<Person, bool>> where){
var result = await _context.People.Where(where).ToListAsync();
return result;
}
通常,我的存储库将返回响应或DTO,但现在它只是返回模型。不过这无法完成。我的推荐人显然是
Core <- Infrastructure <- API
因此在“ Core”界面中,我有以下内容:
Taks<List<Person>> GetGeneric(Expression<Func<AppPerson, bool>> where);
但是Core
不了解AppPerson
,只知道Person
。
这迫使我更改业务逻辑/用例,因此不必:
...Handle(...){
//I can't do this, because the type of P is defined as per the interface as being AppPerson, but core can only see Person.
await _repository.GetGeneric(p => p.Name.Contains("MyName"));
await _repository.GetGeneric(p => p.Name.Contains("MyName") && p.Age > 10);
}
然后,我将不得不在基础架构中的某个地方将一个人映射到一个应用程序人,然后在其中构造where子句,这似乎违反了整个目的。
或者,我当然可以为每个逻辑功能都拥有存储库功能,而不是使它通用,但这似乎也是错误的。
我的直觉告诉我我缺少某些东西,或者我做错了-我可以闻到即将出现的Domain / DAL模型的意大利面条。那么对此有什么解决方案?或最佳做法是什么?