小编Tse*_*eng的帖子

领域驱动设计中的规范模式

我一直在努力解决与规范有关的DDD相关问题,我已经阅读了很多关于DDD和规范和存储库的内容.

但是,如果尝试在不破坏域驱动设计的情况下组合所有这三个,则会出现问题.它归结为如何应用具有性能的过滤器.

首先是一些明显的事实:

  1. 获取DataAccess/Infrastructure Layer的存储库
  2. 域模型表示业务逻辑并转到域层
  3. 数据访问模型表示持久层,并转到Persistance/Infrastructure/DataAccess层
  4. 业务逻辑转到域层
  5. 规格是业务逻辑,因此它们也属于域层.
  6. 在所有这些示例中,在存储库中使用ORM框架和SQL Server
  7. 持久性模型可能不会泄漏到域层

到目前为止,这么容易.当/如果我们尝试将规范应用于存储库而不破坏DDD模式或存在性能问题时,就会出现问题.

申请规格的可能方式:

1)经典方式:使用域层中的域模型的规范

应用传统的规格模式,使用IsSatisfiedBy方法,返回bool和复合规格以组合多个规格.

这让我们保持域层的规范,但......

  1. 它必须与域模型一起使用,而存储库使用持久性模型来表示持久层的数据结构.这个很容易修复使用映射器,如AutoMapper.
  2. 但是,问题无法解决:所有规格都必须在内存中执行.在大型表/数据库中,如果您必须遍历所有实体仅过滤掉符合您规范的实体,这意味着巨大的影响

2)使用持久性模型的规范

这类似于1),但在规范中使用持久性模型.这允许直接使用规范作为我们的.Where谓词的一部分,它将被转换为查询(即TSQL),并且将在持久性存储(即SQL Server)上执行过滤.

  1. 虽然这会提供良好的性能,但它显然违反了DDD模式.我们的持久性模型泄漏到域层,使得域层依赖于持久层,而不是相反.

3)像2),但使规范成为持久层的一部分

  1. 这不起作用,因为域层需要引用规范.它仍然依赖于持久层.
  2. 我们在持久层内部会有业务逻辑.这也违反了DDD模式

4)像3一样,但使用抽象规范作为接口

我们在Domain层中有规范接口,我们在持久层中的规范的具体实现.现在我们的域层只与接口交互而不依赖于持久层.

  1. 这仍然违反了3)中的#2.我们在持久层中会有业务逻辑,这很糟糕.

5)将表达式树从域模型转换为持久性模型

这当然解决了这个问题,但这是一项非常重要的任务,但它会将规范保留在我们的域层内,同时仍然受益于SQL优化,因为规范成为Repositories Where子句的一部分并转换为TSQL

我试过这种方法,有几个问题(表单实现方面):

  1. 我们需要从Mapper知道配置(如果我们使用它)或保留我们自己的映射系统.这可以部分完成(使用AutoMapper读取Mapper配置),但存在进一步的问题
  2. 对于模型A的一个属性映射到模型B的一个属性的情况是可接受的.如果类型不同(即由于持久性类型,例如枚举被保存为另一个表中的字符串或键/值对,并且我们需要在解析器内进行转换.
  3. 如果多个字段映射到一个目标字段,它会变得非常复杂.我认为这不是域模型 - >持久性模型映射的问题

**6)查询生成器,如API**

最后一个是制作某种查询API,该API被传递到规范中,并且Repository/Persistence层将从中生成表达式树以传递给.Where子句,并使用接口来声明所有可过滤字段.

我也朝这个方向做过几次尝试,但对结果并不太满意.就像是

public interface IQuery<T>
{
    IQuery<T> Where(Expression<Func<T, T>> predicate);
}
public interface IQueryFilter<TFilter>
{
    TFilter And(TFilter other);
    TFilter Or(TFilter other);
    TFilter Not(TFilter other);
}

public interface IQueryField<TSource, IQueryFilter>
{
    IQueryFilter …
Run Code Online (Sandbox Code Playgroud)

domain-driven-design specifications repository repository-pattern

21
推荐指数
3
解决办法
8722
查看次数

使用IActionResult作为Actions中的结果类型的优点

使用IActionResultWebApi控制器的返回类型而不是您想要返回的实际类型有什么优势或建议?

我见过的大多数示例都返回了IActionResult,但是当我构建我的第一个站点时,我专门使用View Model类作为我的返回类型....现在我觉得我做错了!

asp.net-core-mvc asp.net-core

21
推荐指数
1
解决办法
2万
查看次数

如何设置Swashbuckle与Microsoft.AspNetCore.Mvc.Versioning

我们有asp.net核心webapi.我们添加Microsoft.AspNetCore.Mvc.VersioningSwashbuckle拥有昂首阔步的UI.我们将控制器指定为:

[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class ContactController : Controller
{
Run Code Online (Sandbox Code Playgroud)

当我们运行swagger ui时,我们在路由中获取版本作为参数: 在此输入图像描述

如何为路由设置默认"v1"?如果第2版进入舞台,那两个版本的支持是如何支持swagger ui的?

swagger asp.net-core-mvc swashbuckle asp.net-core

20
推荐指数
6
解决办法
5803
查看次数

是否从.NET标准库支持EF Core添加迁移?

我们一直在尝试在.Net Standard 1.6类库中运行EF Core Migration,但它一直在失败.但是同样在.Net Core 1.1类库中传递得非常好.

.NET STANDARD是否支持EF Migration?

c# entity-framework-core asp.net-core .net-standard

20
推荐指数
3
解决办法
1万
查看次数

如何在ASP.NET Core 1.0的DI中的Startup类中添加IHttpContextAccessor?

在ASP.NET Core RC 1中,我使用以下代码检索上下文的值(页面的完整地址).然后我在配置中记录了这个值.

public class Startup
{
        public IConfigurationRoot Configuration { get; set; }
        private IHostingEnvironment CurrentEnvironment { get; set; }
        private IHttpContextAccessor HttpContextAccessor { get; set; }
        public Startup(IHostingEnvironment env,
                IHttpContextAccessor httpContextAccessor)
            {                
                var builder = new ConfigurationBuilder()
                    .SetBasePath(env.ContentRootPath)
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

                if (env.IsDevelopment())
                {
                    builder.AddUserSecrets();
                }
                builder.AddEnvironmentVariables();
                Configuration = builder.Build();
                CurrentEnvironment = env;
                HttpContextAccessor = httpContextAccessor;
            }
        public void ConfigureServices(IServiceCollection services)
        {
        ...

        services.AddOptions();
        services.Configure<WebAppSettings>(configuration);
        services.Configure<WebAppSettings>(settings =>
        {
            ...
            settings.WebRootPath = CurrentEnvironment.WebRootPath; …
Run Code Online (Sandbox Code Playgroud)

c# asp.net-core-mvc asp.net-core asp.net-core-1.0

19
推荐指数
2
解决办法
2万
查看次数

实体类型'IdentityUserLogin <string>'需要定义主键

我在linux上使用dotnet core 1.1,当我想从我的常规dbContext中分离identityContext时,我遇到问题,每当我在startup.cs中运行以下行时 - > configure:

//... some other services
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
    serviceScope.ServiceProvider.GetService<ApplicationDbContext>().Database.Migrate();
    //running other database.migrations here + seeding data. But it is the line above that causes problems
Run Code Online (Sandbox Code Playgroud)

因此,该行抛出异常:实体类型'IdentityUserLogin'需要定义主键

我根本不明白这一点,为什么我的工作是给IdentityUserLogin一个主键?它是一个第三方类,我甚至没有触及它.我有以下简单的设置:

namespace EsportshubApi.Models
{
    public class ApplicationDbContext :  IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }

        public ApplicationDbContext()
        {

        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);


        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和applicationUser:

namespace EsportshubApi.Models.Entities
{

    public class ApplicationUser : IdentityUser
    {
        public ApplicationUser() { }

        public …
Run Code Online (Sandbox Code Playgroud)

c# entity-framework asp.net-identity asp.net-core

19
推荐指数
3
解决办法
2万
查看次数

依赖注入按名称解析

我如何为特定类注入不同的对象实现?

例如,在统一中我可以:定义两个实现 IRepository

container.RegisterType<IRepository, TestSuiteRepositor("TestSuiteRepository");
container.RegisterType<IRepository, BaseRepository>(); 
Run Code Online (Sandbox Code Playgroud)

并致电所需的实施

public BaselineManager([Dependency("TestSuiteRepository")]IRepository repository)
Run Code Online (Sandbox Code Playgroud)

c# dependency-injection asp.net-core

18
推荐指数
5
解决办法
1万
查看次数

将查询参数绑定到ASP.NET Core中的模型

我试图使用从查询参数到对象的模型绑定进行搜索.

我的搜索对象是

[DataContract]
public class Criteria 
{
  [DataMember(Name = "first_name")]
  public string FirstName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的控制器有以下操作

[Route("users")]
public class UserController : Controller 
{
  [HttpGet("search")]
  public IActionResult Search([FromQuery] Criteria criteria)
  {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

当我按如下方式调用端点.../users/search?first_name=dave时,控制器操作的criteria属性为null.但是,我可以将端点称为蛇案例.../users/search?firstName=dave,而criteria属性包含属性值.在这种情况下,模型绑定已经起作用,但是当我使用snake_case时却没有.

如何在模型绑定中使用snake_case?

c# asp.net asp.net-mvc model-binding asp.net-core

18
推荐指数
3
解决办法
2万
查看次数

NormalizedUserName VS DotNet Core中的用户名

我正在尝试为MongoDB创建IUserLoginStore的自定义实现,我在使用时注意到了

UserManager<ApplicationUser>
Run Code Online (Sandbox Code Playgroud)

用这个方法

 var userResult = await _userManager.CreateAsync(user);
Run Code Online (Sandbox Code Playgroud)

它经历了实施

GetUserNameAsync
FindByNameAsync
SetNormalizedUserNameAsync
GetUserIdAsync
Run Code Online (Sandbox Code Playgroud)

我想澄清两个问题:

  • 拥有NormalizedUsername和UserName的目的是什么?唯一的区别是我能注意到normalizedUserName是大写的.

  • 我只使用我的实现来存储来自外部登录(Google plus)的用户,有没有办法我可以省略用户名和NormilizedUserName,因为基本上,我在这三个领域使用电子邮件,我感觉我复制数据对我来说没有任何意义.

任何建议?

asp.net-identity asp.net-core-mvc asp.net-core-identity

17
推荐指数
2
解决办法
7547
查看次数

从Controller中将EditorTemplate作为局部视图返回

我想从我的控制器返回一个EditorTemplate作为Partial View.

我目前在做:

public ActionResult Create([Bind(Prefix="Create")]CreateViewModel model)
{
    return PartialView("~/Views/Shared/EditorTemplates/Template.cshtml", model);
}
Run Code Online (Sandbox Code Playgroud)

问题是,在我这样做之后,Create_前缀远离我的观点.有没有办法将编辑器模板作为局部视图返回并保留前缀?

Index.cshtml @model IndexViewModel

@using(Html.BeginForm("Create"))
{
    @Html.EditorFor(m => m.Create, "Template")

    <input type="submit" value="Save" />
}
Run Code Online (Sandbox Code Playgroud)

我正在通过AJAX调用提交此表单.当我最初调用EditorFor时,所有字段都有一个前缀Create_.但是,在我提交表单并返回此PartialView后,前缀将丢失.

.net asp.net-mvc mvc-editor-templates asp.net-mvc-3

15
推荐指数
1
解决办法
7154
查看次数