在别人的代码中可以找到什么? .NET的一些有用的材料

哈Ha! 我们的同事Scott Hanselman认为,在学习编程语言的过程中,这不仅对编写代码和练习写作很重要,而且对学习他人的代码也很重要。 “阅读别人的代码,”斯科特说,并引用了他在同事的工作中发现的有用材料。 削减更多细节!



地板交给斯科特·汉瑟曼 你同意他吗?

学习编程语言的最佳方法不仅是编写更多的代码,而且还要熟悉其示例 ! 这些并不总是示例代码的示例,并且您所看到的大部分内容都不会派上用场,但这是拓宽视野的好方法。

我认为,事实上,阅读代码并没有得到应有的重视。 可能没有足够的干净代码库。

因此,当我发现一个名为Jimmy Bogard Contoso University的代码库时,我感到非常惊喜。

该存储库有很多不错的资料,但是我不会说我已阅读了所有内容,并按照我们的意愿进行了深思熟虑。 要详细研究所有内容,您需要花费一整天的时间。 但是,我喜欢一些要点,并记下了这些要点。 各个代码段显然是按照吉米(Jimmy)的风格编写的,就像他为自己编写的一样。

这根本不是责备。 随着时间的流逝,我们都会积累模板,创建库并开发自己的建筑风格。 我喜欢吉米收集了他本人或多年来参与的有趣事态发展,并准备了不错的阅读材料这一事实。 吉米指出, ContosoUniversityDotNetCore-Pages有很多有用的东西:


克隆和组装工作良好


我有时会降低标准,您会感到惊讶。 很多时候,我会克隆未经任何地方测试的其他人的git存储库。 通过build.ps1下载,我将获得所有需要的奖励。 我的系统上已经安装了.NET Core 2.x ,build.ps1接收必要的软件包并完全构建代码。

关于这个项目有很多意见。 这很棒,因为这是我学习以前从未使用过的方法和工具的方式。 如果有人使用非标准方法,那么在标准工具中就没有必要了!

  • Build.ps1使用从Powershell构建自动化工具PSake提取的构建脚本样式。
  • 它将程序集放置在标准名称为./artifacts的文件夹中。
  • Build.ps1使用Roundhouse ,这是.NET的数据库迁移实用程序,它使用SQL文件和使用projectroundhouse版本控制工具创建的版本。
  • 它被配置为可连续集成到AppVeyor中AppVeyor是我自己使用的出色CI / CD系统。
  • 她使用OctopusDeploy中的Octo.exe工具来打包工件。

代码井井有条


我认为,所有代码都非常易于阅读。 我从Startup.cs开始,只是了解正在使用什么中间件。

public void ConfigureServices(IServiceCollection services) { services.AddMiniProfiler().AddEntityFramework(); services.AddDbContext<SchoolContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddAutoMapper(typeof(Startup)); services.AddMediatR(typeof(Startup)); services.AddHtmlTags(new TagConventions()); services.AddMvc(opt => { opt.Filters.Add(typeof(DbContextTransactionPageFilter)); opt.Filters.Add(typeof(ValidatorPageFilter)); opt.ModelBinderProviders.Insert(0, new EntityModelBinderProvider()); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddFluentValidation(cfg => { cfg.RegisterValidatorsFromAssemblyContaining<Startup>(); }); } 

在这里,我看到使用的库和帮助器,例如AutoMapper,MediatR和HtmlTags。 接下来,我将进入不同的部分并研究每种工具。

微型轮廓仪


我一直喜欢MiniProfiler工具。 这个秘密的.NET宝藏已经创建了很长时间,并且在工作中总是有用的。 我在2011年提到过他! 它不可见地显示在您的网页上,并提供有关站点行为和关键运行时值的非常有用的数据。



建议将它与EF Core一起使用,以查看生成的SQL代码。 一切都将在创建时嵌入到站点中。



太好了!

清除单元测试


Jimmy使用XUnit,我在列表中看到IntegrationTestBase文件 我不了解某些要点,例如SliceFixture文件的操作。 拿了他的笔记来彻底理解一切。 这里不太可能启动新的测试辅助库的创建:过于通用和认真的方法无法在此模板中使用它。

Jimmy使用CQRS (命令查询职责隔离)模式。 首先,创建并运行创建命令,然后执行查询以确认结果。 一切都非常清楚,我们得到了一个非常孤立的测试。

 [Fact] public async Task Should_get_edit_details() { var cmd = new Create.Command { FirstMidName = "Joe", LastName = "Schmoe", EnrollmentDate = DateTime.Today }; var studentId = await SendAsync(cmd); var query = new Edit.Query { Id = studentId }; var result = await SendAsync(query); result.FirstMidName.ShouldBe(cmd.FirstMidName); result.LastName.ShouldBe(cmd.LastName); result.EnrollmentDate.ShouldBe(cmd.EnrollmentDate); } 

流体验证


fluentvalidation是有用的库,用于创建具有强类型控制的清晰验证规则。 Jimmy到处使用它,并获得非常清晰的验证码。

 public class Validator : AbstractValidator<Command> { public Validator() { RuleFor(m => m.Name).NotNull().Length(3, 50); RuleFor(m => m.Budget).NotNull(); RuleFor(m => m.StartDate).NotNull(); RuleFor(m => m.Administrator).NotNull(); } } 

有用的解决方案


让我们看看作者在C#项目扩展中使用了哪些方法。 他认为这表明基本功能缺乏什么。 该方法允许您从Razor Pages以JSON格式返回数据。

 public static class PageModelExtensions { public static ActionResult RedirectToPageJson<TPage>(this TPage controller, string pageName) where TPage : PageModel { return controller.JsonNet(new { redirect = controller.Url.Page(pageName) } ); } public static ContentResult JsonNet(this PageModel controller, object model) { var serialized = JsonConvert.SerializeObject(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); return new ContentResult { Content = serialized, ContentType = "application/json" }; } } 

分页清单


我一直想知道如何处理像PaginatedList这样的辅助类。 对于包装而言太小,对于嵌入而言太具体。 你觉得呢

 public class PaginatedList<T> : List<T> { public int PageIndex { get; private set; } public int TotalPages { get; private set; } public PaginatedList(List<T> items, int count, int pageIndex, int pageSize) { PageIndex = pageIndex; TotalPages = (int)Math.Ceiling(count / (double)pageSize); this.AddRange(items); } public bool HasPreviousPage { get { return (PageIndex > 1); } } public bool HasNextPage { get { return (PageIndex < TotalPages); } } public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize) { var count = await source.CountAsync(); var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(); return new PaginatedList<T>(items, count, pageIndex, pageSize); } } 

我一直在探索可以找到的任何代码源。 我记下自己喜欢的事物,记下我不知道或不理解的内容,并列出要阅读的主题。 我建议您也这样做! 吉米(Jimmy) ,谢谢您编写了如此出色的代码模板 ,我们可以阅读和学习!

Source: https://habr.com/ru/post/zh-CN418519/


All Articles