当前位置: 首页 > news >正文

苏州建设招聘信息网站宣传软文模板

苏州建设招聘信息网站,宣传软文模板,设计案例,建设银行扬中网站原文链接#xff1a;https://codewithmukesh.com/blog/specification-pattern-in-aspnet-core/在本文中#xff0c;我们将讨论在 ASP.NET Core 应用程序中实现规约模式以及它如何增强现有的泛型仓储模式。我们将从头开始构建具有泛型仓储模式、Entity Framework Core的 ASP.N… 原文链接https://codewithmukesh.com/blog/specification-pattern-in-aspnet-core/在本文中我们将讨论在 ASP.NET Core 应用程序中实现规约模式以及它如何增强现有的泛型仓储模式。我们将从头开始构建具有泛型仓储模式、Entity Framework Core的 ASP.NET Core WebAPI并最终实现规约模式模式。您可以在此处找到此实现的完整源代码[1]。让我们开始吧。理解规约模式为什么让我们通过一个简单的示例来了解使用规约模式的必要性。下面是Developer类的代码片段它具有Name、Email、Experience等所需的属性。public class Developer {public int Id { get; set; }public string Name { get; set; }public string Email { get; set; }public int YearsOfExperience {get;set;}public decimal EstimatedIncome {get;set;}public int Followers { get; set; } } 现在我们可能会有一个服务层它通过像Entity Framework Core这样的抽象从DB返回数据集。这是它的样子。public class DeveloperService : IDeveloperService {private readonly ApplicationDbContext _context;public DeveloperService(ApplicationDbContext context){_context  context;}public async TaskIEnumerableDeveloper GetDeveloperCount(){// return a count of all developers in the database} } 虽然您将获得所有开发人员的数量但更实际和合乎逻辑的要求是使用某种过滤器获得开发人员的数量同意吗例如获取估计收入为 100,000 美元或以上的开发人员的数量或具有 5 年或以上经验的开发人员的数量。可能性是无限的。但是这最终会让您拥有大量的服务层函数例如 GetDeveloperCountWithSalariesGreaterThan(decimal minSalary)、GetDeveloperCountWithExperienceMoreThan(int minExp) 等等。需求越多您最终拥有的功能数量就越多。如果您需要薪水高于 x 且经验高于 y 年的开发人员数量怎么办  这是另一个可能导致额外方法的挑战。您可能会争辩说您可以将这些过滤器直接应用于Entity Framework Core实体例如await _context.Developers.Where(aa.Salary  10000  a.Experience  6).ToListAsync() 但是,不,这与您需要的干净的应用程序代码库相去甚远。这种方法最终会很快破坏应用程序的可伸缩性相信我这根本无法维护。小提示您的应用程序中始终需要一个位于应用程序和数据库之间的服务层并全权负责处理业务逻辑。这是您的应用程序需要使用规约模式的地方。注意泛型仓储模式有一些限制这些限制是通过使用规约模式解决的。我们将建立一个项目然后使用规约。我们将建造什么为了演示 ASP.NET Core 中的规约模式我们将构建一个具有2个端点的简单Web API应用程序返回特定的开发人员详细信息返回开发人员列表但是我们将添加泛型仓储模式和工作单元的组合使这个实现更加合乎逻辑和实用。我们将在这里专门识别和实现规约模式的用例。这几乎是您使用 ASP.NET Core 5.0 构建完整应用程序时所需的一切。让我们开始吧。PS你可以在这里找到这个实现的完整源代码。设置项目首先让我们打开 Visual Studio 2019 并创建一个新的解决方案和一个 WebAPI 项目。请注意我们也将在此实现中遵循六边形架构以保持解决方案的良好组织。添加API项目后让我们再向此解决方案添加2个类库项目。我们称之为Data和Core。Data是与数据库和上下文相关的所有实现所在的地方。Core是我们将添加接口和域实体的地方。这就是现阶段解决方案的样子。添加所需的模型如前所述在Core项目中创建一个名为Entities的新文件夹并向其中添加2个类即Developer和Address。public class Address {public int Id { get; set; }public string City { get; set; }public string Street { get; set; } } public class Developer {public int Id { get; set; }public string Name { get; set; }public string Email { get; set; }public int YearsOfExperience { get; set; }public decimal EstimatedIncome { get; set; }public Address Address { get; set; } } 添加 DBContext 、Migrations和必需的包现在让我们将所需的NuGet包安装到相应的项目中。打开包管理器控制台并从下拉列表中将Data项目设置为默认项目。 运行以下命令以安装所需的软件包。Install-Package Microsoft.EntityFrameworkCore Install-Package Microsoft.EntityFrameworkCore.SqlServer Install-Package Microsoft.EntityFrameworkCore.Tools 接下来将API项目设置为默认项目并运行以下命令。Install-Package Microsoft.EntityFrameworkCore.Design 在设置应用程序上下文类之前让我们添加连接字符串。为此从API项目打开 appsettings.json并添加以下内容。请注意我们目前正在使用SQLServer Local DB进行此演示。ConnectionStrings: {DefaultConnection: Data Source(localdb)\\mssqllocaldb;Initial Catalogspecification-pattern-demo;Integrated SecurityTrue;MultipleActiveResultSetsTrue }, 完成后让我们创建所需的上下文类以帮助我们访问数据库。为此在数据项目下添加一个新类并将其命名为ApplicationDbContext。public class ApplicationDbContext : DbContext {public ApplicationDbContext(DbContextOptions options) : base(options){}public DbSetDeveloper Developers { get; set; }public DbSetAddress Addresses { get; set; } } 在这里您可以看到我们提到了要包含在 Application Db Context 中的 Developer 和 Address 类。接下来我们需要将此上下文添加到我们的ASP.NET Core应用程序的服务容器并配置连接详细信息。在API工程中打开Startup.cs在ConfigureServices方法下添加如下内容。services.AddDbContextApplicationDbContext(options  options.UseSqlServer(Configuration.GetConnectionString(DefaultConnection))); 最后我们准备添加迁移并更新数据库。再次打开包管理器控制台并将Data项目设置为默认项目。运行以下命令add-migration initial update-database 这是演示相同内容的屏幕截图。请注意您可能会收到有关上述小数属性精度的警告。我们暂时可以忽略它。完成后我们的数据库现在应该准备好了所需的表和相应的字段。出于演示目的我使用 Visual Studio 2019 IDE 的 SQL Server 对象资源管理器工具将一些示例数据直接添加到数据库中。实现泛型仓储模式由于我们的需求是返回开发人员的结果集所以我们创建一个泛型仓储模式以便它可以使用 ApplicationDbContext 从数据库中查询数据。使用泛型仓储模式的重要性在于此代码也可以重用于多个其他实体。例如我们稍后添加一个名为 Product 的新实体您不一定需要添加用于从数据库访问 Product 数据的新类但您可以在大多数用例中使用现有的泛型仓储库实现。请注意我们将在本文后面的部分讨论和解决泛型仓储库模式的一些限制。在 Core 项目下添加一个新文件夹并将其命名为 Interfaces。在这里添加一个新接口IGenericRepository。public interface IGenericRepositoryT where T: class {TaskT GetByIdAsync(int id);TaskListT GetAllAsync(); } 创建泛型仓储实现现在让我们实现上面创建的接口。由于我们遵循六边形/洋葱架构我们将不得不在应用程序核心之外添加实现。这意味着所有与数据相关的实现都将添加到数据项目中。在这里添加一个新类 GenericRepository。public class GenericRepositoryT : IGenericRepositoryT where T : class {protected readonly ApplicationDbContext _context;public GenericRepository(ApplicationDbContext context){_context  context;}public async TaskListT GetAllAsync(){return await _context.SetT().ToListAsync();}public async TaskT GetByIdAsync(int id){return await _context.SetT().FindAsync();} } 可以看到我们正在将 ApplicationDbContext 的实例注入到这个仓储实现的构造函数中。此实例进一步用于从数据库读取数据。最后在API工程的Startup.cs中添加如下内容将IGenericRepository接口注册到应用的服务容器中。services.AddScoped(typeof(IGenericRepository), (typeof(GenericRepository))); 泛型仓储模式的问题反模式一些开发人员认为泛型仓储是一种反模式。如果使用不当是的任何模式都会弄乱您的代码。对泛型仓储的主要抱怨是单个方法可能会将整个数据库访问代码暴露给用户。这也可能意味着需要针对每种需求组合使用多种方法如本文开头所述。例如看下面的接口声明:ListT FindAsync(ExpressionFuncT, bool query); 此方法可以作为泛型仓储模式的一部分来解决我们遇到的问题。但是由于该方法过于笼统泛型仓储不可能知道我们传递给它的表达式。另一个想法可能是从 IGenericRepository 接口中删除此方法并在新接口中使用它例如从 IGenericRepository 派生的 IDeveloperRepository。这可能会奏效但考虑到未来实体的添加和需求的变化这种变化不是一个明智的选择。想象一下有 20-30 个新实体并且必须创建大量新仓储不是个好主意是吗考虑在 IDevloperRepository 及其实现中具有多种方法例如 GetDevelopersWithSalariesGreaterThan(decimal salary)和 GetDevelopersWithExperienceLessThan(int years)不简洁是吗如果有更简洁的方法来解决这个需求呢这正是规约模式派上用场的地方。在 ASP.NET Core 中使用规约模式增强仓储模式规约模式乍一看可能会觉得很复杂。我也感觉到了。但是一旦您添加了某些基类和评估器您所要做的就是创建规约类根据您的要求这些类通常为 2 到 10 行。让我们开始使用 ASP.NET Core 中的规约模式。在 Core 项目下添加一个新文件夹并将其命名为 Specifications。这是所有与规约相关的接口都要去的地方。创建一个新接口并将其命名为 ISpecification.cspublic interface ISpecificationT {ExpressionFuncT, bool Criteria { get; }ListExpressionFuncT, object Includes { get; }ExpressionFuncT, object OrderBy { get; }ExpressionFuncT, object OrderByDescending { get; } } 这只是一个最小的实现。让我解释每个声明的方法定义。Criteria - 您可以在此处添加基于实体的表达式。Includes – 如果要包含外键表数据可以使用此方法添加它。OrderBy 和 OrderByDescending 是不言自明的。接下来在同一文件夹中添加一个新类 BaseSpecifcation。这将是 ISpecification 接口的实现。public class BaseSpecifcationT : ISpecificationT {public BaseSpecifcation(){}public BaseSpecifcation(ExpressionFuncT, bool criteria){Criteria  criteria;}public ExpressionFuncT, bool Criteria { get; }public ListExpressionFuncT, object Includes { get; }  new ListExpressionFuncT, object();public ExpressionFuncT, object OrderBy { get; private set; }public ExpressionFuncT, object OrderByDescending { get; private set; }protected void AddInclude(ExpressionFuncT, object includeExpression){Includes.Add(includeExpression);}protected void AddOrderBy(ExpressionFuncT, object orderByExpression){OrderBy  orderByExpression;}protected void AddOrderByDescending(ExpressionFuncT, object orderByDescExpression){OrderByDescending  orderByDescExpression;} } 在这里我们将添加3个基本方法和一个构造函数。将表达式添加到 Includes 属性将表达式添加到 OrderBy 属性将表达式添加到 OrderByDescending 属性您可以注意到我们还有一个接受条件的构造函数。Criteria 可以是 ( xx.Salary 100 )  等。你明白了是吗升级泛型仓储首先让我们在 IGenericRepository 接口中添加一个方法。IEnumerableT FindWithSpecificationPattern(ISpecificationT specification  null); 接下来让我们在 GenericRepository 类中实现新方法。public IEnumerableT FindWithSpecificationPattern(ISpecificationT specification  null) {return SpecificationEvaluatorT.GetQuery(_context.SetT().AsQueryable(), specification); } 现在设置所有这些背后的想法是创建可以返回特定结果集的单独规约类。这些新规约类中的每一个都将从 BaseSpecification 类继承。明白了吗现在让我们创建这些规约类以便它有意义 ????因此让我们得出 2 个要求/规约1.按薪水降序返回开发人员列表的规约。2.另一个规约返回具有 N 或以上经验的开发人员列表及其地址。在 Core 项目的同一个 Specification 文件夹下添加我们的第一个规约类 DeveloperByIncomeSpecificationpublic class DeveloperByIncomeSpecification : BaseSpecifcationDeveloper {public DeveloperByIncomeSpecification(){            AddOrderByDescending(x  x.EstimatedIncome);} } 在这里您可以看到我们从 BaseSpecification 类派生并在构造函数中使用 AddOrderByDescending 方法。理想情况下此规约将返回一个按收入递减顺序排列的开发人员列表。接下来让我们添加另一个类DeveloperWithAddressSpecificationpublic class DeveloperWithAddressSpecification : BaseSpecifcationDeveloper {public DeveloperWithAddressSpecification(int years) : base(xx.EstimatedIncome  years){AddInclude(x  x.Address);} } 因此这里我们将查询表达式传递给 Specification Class 的基类它是 BaseSpecification 的构造函数然后将其添加到我们之前创建的 Criteria 属性中。其实很简单。现在随着我们的规约类准备就绪让我们添加 api 端点。在 API 项目下在 Controllers 文件夹下添加一个新的 API Controller并将其命名为 DevelopersController。public class DevelopersController : ControllerBase {public readonly IGenericRepositoryDeveloper _repository;public DevelopersController(IGenericRepositoryDeveloper repository){_repository  repository;}[HttpGet]public async TaskIActionResult GetAll(){var developers  await _repository.GetAllAsync();return Ok(developers);}[HttpGet({id})]public async TaskIActionResult GetById(int id){var developer  await _repository.GetByIdAsync(id);return Ok(developer);}[HttpGet(specify)]public async TaskIActionResult Specify(){var specification  new DeveloperWithAddressSpecification(3);//var specification  new DeveloperByIncomeSpecification();var developers  _repository.FindWithSpecificationPattern(specification);return Ok(developers);} } 第 3 – 7 行将 IGenericRepository 注入到 Controller 的构造函数中。第 8 – 19 行使用仓储实例返回所有开发人员和具有特定 Id 的开发人员的标准端点。第 20 – 27 行这是控制器最有趣的部分。这里的第 23 行和第 24 行是我们之前创建的 2 个规约类。这只是为了证明可以在控制器或使用 GenericRepository 的任何地方创建任何此类规约实例。我们将使用 DeveloperWithAddressSpecification(3) 进行演示。现在让我们运行应用程序并检查指定端点的结果。可以看到还返回了地址数据。现在回到控制器注释掉第 24 行让我们暂时使用 DeveloperByIncomeSpecification。再次运行应用程序。现在您可以注意到没有返回地址数据。为什么很简单因为我们使用了不同的规约没有提到添加 Address 实体。相反该规约按收入的递减顺序返回开发人员的集合。简单但整洁对吗这可能是 ASP.NET Core 应用程序中最酷的设计模式之一。很奇怪但这实际上是您可以理解规约模式是什么的时候???? 根据维基百科 - 在计算机编程中规约模式是一种特定的软件设计模式其中可以通过使用布尔逻辑将业务规则链接在一起来重新组合业务规则。该模式经常用于领域驱动设计的上下文中。现在更有意义了是吗业务规则我们要求返回具有一定经验水平或更高级别的开发人员通过链接标准这发生在 DeveloperWithAddressSpecification 类中组合在一起这是一个布尔逻辑。很简单但是太强大了????展望未来这种模式的可能性是无穷无尽的并且非常有助于扩展应用程序。这种模式也可能支持Data-Shaping和分页。非常强大的模式学习曲线很小是吗这是这篇文章的总结。总结在本文中我们介绍了 ASP.NET Core 应用程序中的规约模式以及它如何通过占上风来增强泛型仓储模式。我们还构建了一个完整的 Web API 应用程序该应用程序遵循洋葱架构以进行干净的代码管理。你也可以在我的 Github 上找到完整的源代码。有任何建议或问题吗请随时将它们留在下面的评论部分。Thanks and Happy Coding????欢迎关注我的个人公众号”My IO“参考资料[1]完整源代码: https://github.com/iammukeshm/specification-pattern-asp-net-core
http://wiki.neutronadmin.com/news/264742/

相关文章:

  • 长沙网站设计公司石家庄网站建设方案咨询
  • 网站建设帝国网站源码下载了属于侵权吗
  • 自己开个网站c .net网站开发入门
  • 蓝色系的网站wordpress 加速插件
  • 中国太空网站怎样做竞价推广
  • 建设网站制作实训报告网站改版后seo该怎么做
  • 一个网站的建设步骤是做农业的公司管理网站
  • 重要的网站建设在线做分析图的网站
  • phpcms 网站路径网站开发明细报价表
  • 网站建设实训进程计划专业建设网站公司哪家好
  • 简单的asp网站源码WordPress 教育模板
  • 山东网站开发学校怎么制作商城小程序
  • 做外贸生意最好的网站网络运营策划
  • 做门户网站cmswordpress yusi
  • 留学网站建设网络公司的推广
  • 做网站很火的APP万网 网站建设
  • 专业做室内设计的网站有哪些内容wordpress不显示网站标题
  • 济南网站搭建公司青岛seo推广
  • 网站文章收录查询山西建筑工程集团有限公司
  • 定州网站建设兼职服装行业做推广网站
  • 着力规范网站集约化建设wordpress 留言插件
  • 做网站的流程知乎北戴河区建设局网站
  • pac网站代理seozhun
  • 北理离线《网站开发与应用》平面网页设计教学
  • 网站开发常用js函数官方网站下载拼多多
  • 备案中的网站名称微信开发公司怎么样
  • 网站域名注册哪家好东莞排名推广
  • 网站免费制作教程珠海高端网站建设
  • 阳春做网站公司学习做网站多久
  • 如何让网站火起来wordpress 获取当前文章id