我尝试使用 CQRS 以 DDD 方式实现一些应用程序。我使用 asp.net core 应用程序,以及 Microsoft(在微服务书中)我使用 Mediatr。我想实现文章的过滤。为此,人们建议使用规范模式并将所有规范存储在域中(什么层应包含 DDD 中的查询)。
但是如果我使用dapper,我该如何处理解析表达式呢?对于 EF,这不是问题,但对于原始 SQL,却是问题。我认为不值得将表达式树解析器和转换器实现为 SQL。更简单的方法是在 Domain 中存储一些 FilterModel,然后通过在基础设施模型中遍历该模型来构建 SQL 或 SphinxQl。该解决方案符合 DDD 原则吗?我将不胜感激的建议)
我有一个简单的 DDD 服务,带有文章聚合根。我使用 MediatR 和 CQRS 来分离命令和查询。在 DDD 域中不应依赖于应用程序和基础设施层。我有一个存储库 IArticleRepository,用于从文章数据库中组合一些数据。我有一个休息端点,用于通过某种过滤器获取文章,以便我创建
ArticleQuery : IRequest<ArticleDto(or Article)>
Run Code Online (Sandbox Code Playgroud)
那么这个查询对象应该是什么时候呢?我每个聚合都有一个存储库,因此在域层中我有 IArticleRepository。我需要指定输入参数类型。如果我将查询放在基础设施或应用程序层中,我会获得从域指向基础设施或应用程序的依赖关系。如果我将查询放在域中,则会违反 DDD,因为查询与业务无关。如果我不将对象放入存储库,而仅将字段作为参数放入存储库,则会有大约 10-15 个参数 - 这是代码味道。
它需要,因为在查询处理程序中还出现搜索引擎逻辑,所以我决定通过存储库或类似的东西将来自基础设施中搜索引擎逻辑的 SQL 逻辑封装起来。
我有一个模型:
public class Model
{
public int Id { get;}
public string Name { get; }
public string AnotherName { get; }
}
Run Code Online (Sandbox Code Playgroud)
默认构造函数,没有setter,因此我们在IL生成的类中没有公共setter方法。
但Dapper以某种方式初始化我的数据。所有属性均已填充。
var sql = $@"SELECT id as Id, name as Name, another_name as AnotherName FROM dapper";
var raws = (connection.QueryAsync<Model>(sql).Result).AsList();
Run Code Online (Sandbox Code Playgroud)
我找到了源代码,并且它们通过 Setter 方法进行设置,但是当我尝试像这样获取 setter 时Dapper,我得到了 null methodInfo。这是一些DapperSqlMapper的源代码:3320
if (specializedConstructor == null)
{
// Store the value in the property/field
if (item.Property != null)
{
il.Emit(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, DefaultTypeMap.GetPropertySetter(item.Property, …Run Code Online (Sandbox Code Playgroud) 我进行了以下设置:授权服务器(带有 MVC 的 .NET 6,端口 7000)、客户端(带有 MVC 的 .NET 6,端口 7001)、资源服务器(.NET 6 API,端口 7002)。
授权服务器设置:
builder.Services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = builder.Configuration["ClientId"];
options.ClientSecret = builder.Configuration["ClientSecret"];
});
builder.Services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = Claims.Name;
options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
options.ClaimsIdentity.RoleClaimType = Claims.Role;
options.ClaimsIdentity.EmailClaimType = Claims.Email;
options.SignIn.RequireConfirmedAccount = false;
});
builder.Services.AddOpenIddict()
.AddCore(options =>
{
options.UseEntityFrameworkCore()
.UseDbContext<AuthorizationContext>();
})
.AddServer(options =>
{
options.SetAuthorizationEndpointUris("/connect/authorize")
.SetLogoutEndpointUris("/connect/logout")
.SetTokenEndpointUris("/connect/token")
.SetUserinfoEndpointUris("/connect/userinfo")
.SetIntrospectionEndpointUris("/connect/introspect");
options.RegisterScopes(Scopes.Email, Scopes.Profile, Scopes.Roles);
options.AllowAuthorizationCodeFlow();
options.AddDevelopmentEncryptionCertificate()
.AddDevelopmentSigningCertificate();
options.UseAspNetCore()
.EnableAuthorizationEndpointPassthrough()
.EnableLogoutEndpointPassthrough()
.EnableTokenEndpointPassthrough()
.EnableUserinfoEndpointPassthrough()
.EnableStatusCodePagesIntegration();
})
.AddValidation(options =>
{
options.UseLocalServer();
options.UseAspNetCore();
});
builder.Services.AddHostedService<Worker>(); …Run Code Online (Sandbox Code Playgroud) orm ×2
.net ×1
cqrs ×1
dapper ×1
jwt ×1
oauth ×1
openiddict ×1
reflection ×1
repository ×1
sql ×1