O que pode ser encontrado no código de outra pessoa? Uma seleção de materiais úteis para .NET

Olá Habr! Nosso colega, Scott Hanselman, acredita que, como parte do aprendizado de uma linguagem de programação, é importante não apenas codificar e praticar a escrita, mas também aprender o código de outra pessoa. "Leia o código de outra pessoa", diz Scott, e cita material útil que encontrou no trabalho de seu colega. Mais detalhes sob o corte!



Passo a palavra para Scott Hanselman . Você concorda com ele?

A melhor abordagem para aprender uma linguagem de programação não é apenas escrever mais código, mas também familiarizar-se com seus exemplos ! Nem sempre serão exemplos de código exemplar e muito do que você vê não será útil, mas é uma ótima maneira de ampliar seus horizontes.

Acredito que de fato a leitura do código não recebe a devida atenção. Talvez não haja bases de código limpas suficientes.

Fiquei agradavelmente surpreso quando descobri uma base de código chamada Universidade Jimmy Bogard Contoso .

Este repositório tem muito material bom, mas não direi que li tudo e com a mesma atenção que gostaríamos. Para estudar tudo em detalhes, você precisa passar o dia inteiro. No entanto, gostei de alguns pontos e os tomei nota. Peças individuais de código são claramente feitas no estilo de Jimmy, como ele as escreveu por si mesmo.

Isso não é uma censura. Com o tempo, todos nós acumulamos modelos, criamos bibliotecas e desenvolvemos nossos próprios estilos arquitetônicos. Gosto do fato de Jimmy ter colecionado desenvolvimentos interessantes feitos por ele ou com sua participação ao longo dos anos e preparado um bom material de leitura. Jimmy observa que o ContosoUniversityDotNetCore-Pages tem muitas coisas úteis:


Clonagem e montagem funcionam muito bem


Você ficará surpreso com o quão baixo eu às vezes abaixo a barra. Muitas vezes clono o repositório git de outra pessoa que não foi testado em nenhum lugar. E recebo um bônus por baixar no build.ps1 tudo o que é necessário. O .NET Core 2.x já está instalado no meu sistema , o build.ps1 recebe os pacotes necessários e cria completamente o código.

Há muitas opiniões sobre este projeto. E isso é ótimo, porque é assim que eu aprendo sobre métodos e ferramentas que eu não usei antes. Se alguém usa uma abordagem não padrão, então entre as ferramentas padrão não há necessidade!

  • Build.ps1 usa um estilo de script de compilação retirado do PSake , uma ferramenta de automação de compilação do PowerShell.
  • Coloca a montagem em uma pasta com o nome padrão ./artifacts.
  • Build.ps1 usa Roundhouse , um utilitário de migração de banco de dados para .NET que usa arquivos e versões SQL criados usando a ferramenta de controle de versão projectroundhouse .
  • Ele está configurado para integração contínua ao AppVeyor , o excelente sistema de CI / CD que eu mesmo uso.
  • Ela usa a ferramenta Octo.exe do OctopusDeploy para compactar artefatos.

Código ordenado e claro


Na minha opinião, todo o código é muito fácil de ler. Comecei com o Startup.cs para entender apenas o que o middleware está sendo usado.

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>(); }); } 

Aqui eu vejo as bibliotecas e auxiliares usados, por exemplo, AutoMapper, MediatR e HtmlTags. Em seguida, posso entrar em seções separadas e estudar cada ferramenta.

Miniprofiler


Eu sempre gostei da ferramenta MiniProfiler . Esse tesouro secreto do .NET foi criado por um longo tempo e é sempre útil no trabalho. Eu o mencionei em 2011! Ele está invisivelmente presente na sua página da web e fornece dados REALMENTE úteis sobre o comportamento do site e os principais valores de tempo de execução.



É aconselhável usá-lo com o EF Core para ver também o código SQL gerado. E tudo é incorporado no site à medida que é criado.



Apenas ótimo!

Limpar testes de unidade


Jimmy usa o XUnit e vejo o arquivo IntegrationTestBase na lista . Não entendo alguns pontos, por exemplo, a operação do arquivo SliceFixture . Tomou uma nota para entender tudo. É improvável que a criação de uma nova biblioteca auxiliar de teste seja lançada aqui: abordagem universal e séria demais para usá-la neste modelo.

Jimmy usa o padrão CQRS (Command Query Responsibility Segregation). No início, o comando Criar é criado e executado, e uma consulta é executada para confirmar os resultados. Tudo está muito claro, temos um teste muito isolado.

 [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); } 

Validação de fluido


A validação fluente é uma biblioteca útil para criar regras claras de validação com forte controle de tipo. Jimmy o usa em qualquer lugar e obtém um código de verificação extremamente claro.

 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(); } } 

Soluções úteis


Vamos ver quais métodos a extensão do projeto C # usa pelo autor. Isso mostra o que, na opinião dele, falta na funcionalidade básica. O método permite retornar dados no formato JSON a partir do Razor Pages.

 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


Eu sempre me perguntei o que fazer com classes auxiliares como PaginatedList. Muito pequeno para embalagem, muito específico para incorporação. O que você acha?

 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); } } 

Continuo explorando todas as fontes de código que encontro. Tomo nota das coisas que gosto, anote o que não sei ou não entendo e faço uma lista de tópicos para leitura. Eu aconselho você a fazer o mesmo! Obrigado, Jimmy , por escrever um ótimo modelo de código que podemos ler e aprender!

Source: https://habr.com/ru/post/pt418519/


All Articles