What can be found in someone else's code? Selection of useful materials on .NET

Original author: Scott Hanselman
  • Transfer
Hi, Habr! Our colleague, Scott Hanselman, believes that in the context of learning a programming language, it is important not only to code and practice writing, but also to learn someone else's code. "Read someone else's code," says Scott and cites useful materials that he found in the workings of his colleague. More under the cut!



I give the floor to Scott Hanselman . Do you agree with him?

The best approach to learning a programming language is not only to write more code, but also to get acquainted with its examples ! These are not always examples of exemplary code, and much of what you see is not useful, but it is a great way to broaden your horizons.

I believe that in fact, the reading of the code does not pay enough attention. Perhaps not enough clean code bases.

Therefore, I was pleasantly surprised when I discovered a code base called Jimmy Bogard of Contoso University .

There is a lot of good material in this repository, but I will not say that I read it all and as thoughtfully as I would like. To study everything in detail, you need to spend the whole day. However, I liked some of the points, and noted them. Separate code snippets are clearly made in the style of Jimmy, since he wrote them himself and for himself.

This is not a reproach at all. We all accumulate templates over time, build libraries and develop our own architectural styles. I like that Jimmy collected interesting insights made by himself or with his participation over many years, and prepared good reading material. Jimmy notes that there are many useful things at ContosoUniversityDotNetCore-Pages :


Cloning and assembly work pretty well.


You will be surprised how low I sometimes lower the bar. Very often I clone someone else's git repository that has not been tested anywhere. And I get a bonus for uploading to build.ps1 everything that is needed. On my system, .NET Core 2.x is already installed , build.ps1 receives the necessary packages and builds the code completely.

There are many opinions about this project. And this is great, because I’m learning about methods and tools that I haven’t used before. If someone uses a non-standard approach, it means that among the standard tools there is no need!

  • Build.ps1 uses the build script style taken from PSake , the PowerShell build automation tool.
  • It places the assembly in a folder with the standard name ./artifacts.
  • Build.ps1 uses Roundhouse , a database migration utility for .NET that uses SQL files and versions created using the projectroundhouse version management tool .
  • It is configured for continuous integration into AppVeyor , an excellent CI / CD system that I use myself.
  • It uses the Octo.exe tool from OctopusDeploy to package the artifacts.

Orderly and understandable code


In my opinion, all the code is read very easily. I started with Startup.cs to just understand what middleware is being used.

publicvoidConfigureServices(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 see used libraries and helpers, for example, AutoMapper, MediatR and HtmlTags. Then I can go into separate sections and study each tool.

MiniProfiler


I always liked the MiniProfiler tool . This secret .NET treasure has been created for a long time and is always useful in work. I mentioned it in 2011! It is discreetly present on your webpage and provides REALLY useful data about the site behavior and key runtime values.



It is advisable to use it with EF Core to see the generated SQL code as well. And everything is built into the site as it is created.



Just great!

Understandable unit tests


Jimmy uses XUnit, and I see the file IntegrationTestBase in the list . Some moments I do not understand, for example, the work of the SliceFixture file . Took it to thoroughly understand everything. It is unlikely that the creation of a new test auxiliary library is launched here: the approach is too universal and serious to use it in this template.

Jimmy applies the CQRS (Command Query Responsibility Segregation) pattern . At the beginning, the Create command is created and launched, then a request is made to confirm the results. Everything is very clear, we get a very isolated test.

[Fact]
publicasync 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


fluentvalidation is a useful library for creating clear validation rules with strict type checking. Jimmy uses it everywhere and gets extremely clear verification code.

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

Useful solutions


Let's see what methods the extension of the C # project uses the author. This shows what, in his opinion, is lacking in the basic functionality. The method allows you to return data in JSON format from Razor Pages.

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

Paginatedlist


I always wondered what to do with helper classes like PaginatedList. Too small for packaging, too specific for embedding. What do you think?

publicclassPaginatedList<T> : List<T>
{
    publicint PageIndex { get; privateset; }
    publicint TotalPages { get; privateset; }
    publicPaginatedList(List<T> items, int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalPages = (int)Math.Ceiling(count / (double)pageSize);
        this.AddRange(items);
    }
    publicbool HasPreviousPage
    {
        get
        {
            return (PageIndex > 1);
        }
    }
    publicbool HasNextPage
    {
        get
        {
            return (PageIndex < TotalPages);
        }
    }
    publicstaticasync 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();
        returnnew PaginatedList<T>(items, count, pageIndex, pageSize);
    }
}

I continue to explore any sources of code that I can find. I take note of things I like, note what I do not know or do not understand, and make a list of topics to read. I would advise you to do the same! Thank you, Jimmy , for writing such a large code pattern that we can read and study!

Also popular now: