Begining
Decision was made I create yet another medium sized application just for fun - it will be a playground and a basis for showing integration with many open libs.
This is my personal strong view how that sized application can be composed - you can have your own view on that and thats fair.
So back to interesting stuff. I will do some single page application with backend on .net core, frontend written in angular and db in sql express. Visual Studio has already some templae for it but personally i like to use dry api from .net core and angular generated by some generator. As I always try to automatize my dev flow regardless of CI vendor I will use cake for that.
All code connected with that will be available at https://github.com/AdaskoTheBeAsT/SurveyApp
Backend
If you look for some good template you can read IMHO great article Removing the MVC Razor dependencies from the Web API template in ASP.NET Core. You can install that template by using following command
dotnet new --install "NetEscapades.Templates::*"
and now you can create folder for your app and then run following command
dotnet new basicwebapi --name <name of your application>.
Job almost done. There are things connected with upgrading .net core to latest version.
You should edit csproj and put there
<PropertyGroup Label="Build">
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Cors" Version="2.2.0" />
</ItemGroup>
Now I have api project in newest .net core version - there will be much more projects adn also test ones so my practice is to create Directory.Build.props in root folder of solution as described in here https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2017. I put there all packages shared by all projecs inside my solution. So there is a place for code static analysis libraries which I am fan of - it is one of the things which I use to minimize problems with my code - I always set "Treat warnings as errors" - when you enforce this you will fix the things - when you leave warnings as it is you will make sacrifices to quality and finally it will be abandoned in your team. Once I tried to put analyzers into some of the existing project which team which I worked in took over from some developers from other country. I put there analyzers and watched 20k warning messages appeared - very disheartening - finally it stayed as it is as nobody has mental power to even start that journey.
Ok so back to Directory.Build.props - i put there analyzers, stylecop configuration for enforcing code style, ruleset configuration for analyzers and LangVersion =latest to use all those new features in c# language ;). Additionally treat warnings as errors set and copying documentation to publish folder (I will get back to this when setting up swagger on api).
<PropertyGroup>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<!-- Based on article https://www.thomaslevesque.com/2017/09/18/common-msbuild-properties-and-items-with-directory-build-props/ -->
<PropertyGroup>
<!-- Common ruleset shared by all projects -->
<CodeAnalysisRuleset>$(MSBuildThisFileDirectory)Survey.ruleset</CodeAnalysisRuleset>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<!-- Add reference to analyzers to all projects -->
<PackageReference Include="AsyncFixer" Version="1.1.6" PrivateAssets="all" />
<PackageReference Include="Asyncify" Version="0.9.7" PrivateAssets="all" />
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.3" PrivateAssets="all" />
<PackageReference Include="Roslynator.Analyzers" Version="2.0.0" PrivateAssets="all" />
<PackageReference Include="Roslynator.CodeFixes" Version="2.0.0" PrivateAssets="all" />
<PackageReference Include="SecurityCodeScan" Version="3.0.0" PrivateAssets="all" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="all" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="7.10.0.7896" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61" PrivateAssets="all" />
<!-- Common StyleCop configuration -->
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" />
</ItemGroup>
<Target Name="CopyDocumentationFile" AfterTargets="ComputeFilesToPublish">
<ItemGroup>
<ResolvedFileToPublish Include="@(FinalDocFile)" RelativePath="@(FinalDocFile->'%(Filename)%(Extension)')" />
</ItemGroup>
</Target>
In project file I defined automatic logs folder creation:
<Target Name="MakeMyDir" AfterTargets="Build">
<MakeDir Directories="$(OutDir)logs" Condition="!Exists('$(OutDir)logs')" />
</Target>
For logging I use Serilog which has some nice features for strucutred logging and also is very performant
Serilog vs NLog performance