Привет, Хабр! Наш коллега, Скотт Хансельман, считает, что в рамках изучения языка программирования важно не только кодить и практиковаться в написании, но и изучать чужой код. «Читайте чужой код» говорит Скотт и приводит полезные материалы, которые он нашел в наработках своего коллеги. Подробнее под катом!
Передаю слово Скотту Хансельману. А вы согласны с ним?
Лучший подход к изучению языка программирования – не только писать больше кода, но и знакомиться с его примерами! Не всегда это будут примеры образцового кода, и многое из увиденного вам не пригодится, но это отличный способ расширить кругозор.
Я считаю, что на самом деле чтению кода не уделяют должного внимания. Возможно, не хватает чистых баз кода.
Поэтому я был приятно удивлен, когда обнаружил базу кода, названную Джимми Богардом Contoso University.
В этом репозитории много хорошего материала, но не буду утверждать, что прочитал его весь и настолько вдумчиво, как хотелось бы. Чтобы детально все изучить, нужно потратить целый день. Однако некоторые моменты мне понравились, и взял их на заметку. Отдельные фрагменты кода явно сделаны в стиле Джимми, поскольку он писал их сам и под себя.
Это вовсе не упрек. Мы все со временем накапливаем шаблоны, формируем библиотеки и разрабатываем собственные архитектурные стили. Мне нравится, что Джимми собрал интересные наработки, сделанные им самим или при его участии за многие годы, и подготовил хороший материал для чтения. Джимми отмечает, что на ContosoUniversityDotNetCore-Pages есть много полезного:
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>(); });
}
[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);
}
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();
}
}
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"
};
}
}
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);
}
}
К сожалению, не доступен сервер mySQL