示例代码-在ASP.NET Core 2.0的Razor页面上有意见的ContosoUniversity

The best way to learn about code isn't just writing more code - it's reading code! Not all of it will be great code and much of it won't be the way you would do it, but it's a great way to expand your horizons.

学习代码的最好方法不仅是编写更多代码,而是在阅读代码! 并非所有代码都将是出色的代码,并且绝大部分代码都不是要做的方式,但这是扩大视野的好方法。

In fact, I'd argue that most people aren't reading enough code. Perhaps there's not enough clean code bases to check out and learn from.

实际上,我认为大多数人没有阅读足够的代码。 也许没有足够干净的代码库可以签出并学习。

I was pleased to stumble on this code base from Jimmy Bogard called Contoso University at https://github.com/jbogard/ContosoUniversityDotNetCore-Pages.

我很高兴在位于https://github.com/jbogard/ContosoUniversityDotNetCore-Pages的名为Contoso University的Jimmy Bogard上偶然发现了此代码库。

There's a LOT of good stuff to read in this repo so I won't claim to have read it all or as deeply as I could. In fact, there's a good solid day of reading and absorbing here.However, here's some of the things I noticed and that I appreciate. Some of this is very "Jimmy" code, since it was written for and by Jimmy. This is a good thing and not a dig. We all collect patterns and make libraries and develop our own spins on architectural styles. I love that Jimmy collects a bunch of things he's created or contributed to over the years and put it into a nice clear sample for us to read. As Jimmy points out, there's a lot in https://github.com/jbogard/ContosoUniversityDotNetCore-Pages to explore:

在此仓库中有很多好东西要阅读,所以我不会声称已阅读全部或尽可能深入的内容。 实际上,这里有很多阅读和吸收的美好时光,但是,这是我注意到的一些事情,我对此表示赞赏。 其中一些代码非常“吉米”,因为它是由吉米(Jimmy)为其编写的。 这是一件好事,而不是挖。 我们都收集模式并制作库,并针对建筑风格开发自己的样式。 我喜欢吉米(Jimmy)收集了他多年来创造或贡献的一堆东西,并将其放入一个清晰的样本中供我们阅读。 正如Jimmy指出的, https//github.com/jbogard/ContosoUniversityDotNetCore-Pages中有很多内容可供探索:

克隆和构建就可以了(Clone and Build just works)

A low bar, right? You'd be surprised how often I git clone someone's repository and they haven't tested it elsewhere. Bonus points for a build.ps1 that bootstraps whatever needs to be done. I had .NET Core 2.x on my system already and this build.ps1 got the packages I needed and built the code cleanly.

低吧,对吧? 您会惊讶于我经常复制某个人的存储库,而他们没有在其他地方对其进行测试。 对于build.ps1的奖金点,该boot.bootstraps需要执行的操作。 我的系统上已经.NET Core 2.x,并且这个build.ps1获得了我需要的软件包并干净地构建了代码。

It's an opinioned project with some opinions. ;) And that's great, because it means I'll learn about techniques and tools that I may not have used before. If someone uses a tool that's not the "defaults" it may me that the defaults are lacking!

这是一些保留意见的opinioned项目。 ;)太好了,因为这意味着我将学习以前可能没有使用过的技术和工具。 如果有人使用不是“默认值”的工具,那么我可能缺少默认值!

  • Build.ps1 is using a build script style taken from PSake, a powershell build automation tool.

    Build.ps1使用的是来自Powershell构建自动化工具PSake的构建脚本样式。

  • It's building to a folder called ./artifacts as as convention.

    按照惯例,它将建立在名为./artifacts的文件夹中。
  • Inside build.ps1, it's using Roundhouse, a Database Migration Utility for .NET using sql files and versioning based on source control http://projectroundhouse.org

    在build.ps1内部,它使用Roundhouse ,这是一个用于.NET的数据库迁移实用程序,它使用sql文件和基于源代码控制的版本控制http://projectroundhouse.org

  • It's set up for Continuous Integration in AppVeyor, a lovely CI/CD system I use myself.

    它是为AppVeyor中的持续集成而设置的, AppVeyor是我自己使用的一个可爱的CI / CD系统。

  • It uses the Octo.exe tool from OctopusDeploy to package up the artifacts.

    它使用OctopusDeploy中的Octo.exe工具打包了工件。

井井有条,易于阅读 (Organized and Easy to Read)

I'm finding the code easy to read for the most part. I started at Startup.cs to just get a sense of what middleware is being brought in.

我发现该代码大部分时候都易于阅读。 我从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>(); });
}
Here I can see what libraries and helpers are being brought in, like AutoMapper, MediatR, and HtmlTags. Then I can go follow up and learn about each one.

MiniProfiler (MiniProfiler)

I've always loved MiniProfiler. It's a hidden gem of .NET and it's been around being awesome forever. I blogged about it back in 2011! It sits in the corner of your web page and gives you REAL actionable details on how your site behaves and what the important perf timings are.

我一直很喜欢MiniProfiler 。 它是.NET的一个隐藏的瑰宝,并且一直以来都很棒。 我在2011年就写了博客! 它位于您网页的一角,为您提供有关网站的行为方式以及重要的性能选择时机的切实可行的详细信息。

MiniProfiler is the profiler you didn't know you needed

It's even better with EF Core in that it'll show you the generated SQL as well! Again, all inline in your web site as you develop it.

使用EF Core会更好,因为它还会向您显示生成SQL! 同样,开发过程中网站上的所有内联代码。

inline SQL in MiniProfiler

Very nice.

非常好。

清洁单元测试 (Clean Unit Tests)

Jimmy is using XUnit and has an IntegrationTestBase here with some stuff I don't understand, like SliceFixture. I'm marking this as something I need to read up on and research. I can't tell if this is the start of a new testing helper library, as it feels too generic and important to be in this sample.

Jimmy使用的是XUnit ,这里有一个IntegrationTestBase以及一些我不了解的东西,例如SliceFixture 。 我将此标记为需要阅读和研究的内容。 我无法确定这是否是新的测试帮助程序库的开始,因为它太普通且太重要了,无法包含在此示例中。

He's using the CQRS "Command Query Responsibility Segregation" pattern. Here starts with a Create command, sends it, then does a Query to confirm the results. It's very clean and he's got a very isolated test.

他正在使用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);
}

FluentValidator (FluentValidator)

https://fluentvalidation.net is a helper library for creating clear strongly-typed validation rules. Jimmy uses it throughout and it makes for very clean validation code.

https://fluentvalidation.net是用于创建清晰的强类型验证规则的帮助程序库。 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();
    }
}

有用的扩展(Useful Extensions)

Looking at a project's C# extension methods is a great way to determine what the author feels are gaps in the underlying included functionality. These are useful for returning JSON from Razor Pages!

查看项目的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)

I've always wondered what to do with helper classes like PaginatedList. Too small for a package, too specific to be built-in? What do you think?

我一直想知道如何处理像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);
    }
}

I'm still reading all the source I can. Absorbing what resonates with me, considering what I don't know or understand and creating a queue of topics to read about. I'd encourage you to do the same! Thanks Jimmy for writing this large sample and for giving us some code to read and learn from!

我仍在阅读所有可以阅读的资料。 吸收引起我共鸣的内容,考虑我不了解或不了解的内容,并创建一个要阅读的主题队列。 我鼓励您也这样做! 感谢Jimmy编写了这个大样本,并给了我们一些阅读和学习的代码!

Sponsor: Scale your Python for big data & big science with Intel® Distribution for Python. Near-native code speed. Use with NumPy, SciPy & scikit-learn. Get it Today!

赞助商:借助适用于Python的英特尔®发行版,将Python扩展到大数据和大科学领域。 接近本机的代码速度。 与NumPy,SciPy和scikit-learn一起使用。 立即获取

翻译自: https://www.hanselman.com/blog/example-code-opinionated-contosouniversity-on-aspnet-core-20s-razor-pages

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值