PI06 i PI06-1. Docker definitions for MSSQL and Postgres. Data seeder/generator for countries and people. Entity Framework example with variants for Postgres and MSSQL
This commit is contained in:
60
DefensiveProgramming/Logging/DataLoader.cs
Normal file
60
DefensiveProgramming/Logging/DataLoader.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Logging;
|
||||
|
||||
public class DataLoader : IDataLoader
|
||||
{
|
||||
private readonly ILogger<DataLoader> logger;
|
||||
|
||||
public DataLoader(ILogger<DataLoader> logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public List<(string, DateOnly)> LoadData(string filename)
|
||||
{
|
||||
List<(string, DateOnly)> list = new();
|
||||
if (!File.Exists(filename))
|
||||
{
|
||||
string message = $"File {filename} does not exist";
|
||||
logger.LogError(message);
|
||||
throw new FileNotFoundException(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
//use File.ReadAllLines for small files
|
||||
using (var reader = new StreamReader(File.OpenRead(filename)))
|
||||
{
|
||||
string? line;
|
||||
while((line = reader.ReadLine()) != null) {
|
||||
string pattern = "[0-3]?[0-9].[0-3]?[0-9].[0-9]{4}.";
|
||||
var match = Regex.Match(line, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
string datetext = line.Substring(match.Index, match.Length);
|
||||
if (DateOnly.TryParseExact(datetext, "d.M.yyyy.", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateOnly date))
|
||||
{
|
||||
var item = (line.Remove(match.Index, match.Length).Trim(), date);
|
||||
logger.LogTrace(item.ToString());
|
||||
list.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Invalid date in line: " + line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("No date found in line: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
9
DefensiveProgramming/Logging/IDataLoader.cs
Normal file
9
DefensiveProgramming/Logging/IDataLoader.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Logging;
|
||||
|
||||
public interface IDataLoader
|
||||
{
|
||||
List<(string, DateOnly)> LoadData(string filename);
|
||||
}
|
||||
30
DefensiveProgramming/Logging/Logging.csproj
Normal file
30
DefensiveProgramming/Logging/Logging.csproj
Normal file
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.6" />
|
||||
<PackageReference Include="NLog" Version="6.1.2" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="6.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="data.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="nlog.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
45
DefensiveProgramming/Logging/Program.cs
Normal file
45
DefensiveProgramming/Logging/Program.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NLog.Extensions.Logging;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Logging;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
using (var serviceProvider = BuildDI())
|
||||
{
|
||||
var dataLoader = serviceProvider.GetRequiredService<IDataLoader>();
|
||||
var list = dataLoader.LoadData("data.txt");
|
||||
var sortQuery = list.OrderByDescending(t => t.Item2)
|
||||
.ThenBy(t => t.Item1);
|
||||
|
||||
Console.WriteLine("Valid data: ");
|
||||
foreach (var item in sortQuery)
|
||||
{
|
||||
Console.WriteLine($"{item.Item2:yyyy-MM-dd} {item.Item1}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ServiceProvider BuildDI()
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json")
|
||||
.Build();
|
||||
|
||||
IServiceCollection services = new ServiceCollection();
|
||||
var provider = services.AddLogging(configure => {
|
||||
configure.AddConfiguration(configuration.GetSection("Logging"));
|
||||
configure.AddConsole();
|
||||
configure.AddNLog(new NLogProviderOptions { RemoveLoggerFactoryFilter = false });
|
||||
})
|
||||
.AddTransient<IDataLoader, DataLoader>()
|
||||
.BuildServiceProvider();
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
9
DefensiveProgramming/Logging/appsettings.json
Normal file
9
DefensiveProgramming/Logging/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Trace",
|
||||
"System": "Warning",
|
||||
"Microsoft": "Trace"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
DefensiveProgramming/Logging/data.txt
Normal file
5
DefensiveProgramming/Logging/data.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Ana 22.5.1988.
|
||||
01.03.1995. Ivan John
|
||||
Ema
|
||||
Mario 15.13.1980.
|
||||
Klara 11.07.1998.
|
||||
31
DefensiveProgramming/Logging/nlog.config
Normal file
31
DefensiveProgramming/Logging/nlog.config
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true"
|
||||
internalLogLevel="Warn"
|
||||
internalLogFile="logs/internal-nlog.txt">
|
||||
|
||||
<!-- the targets to write to -->
|
||||
<targets>
|
||||
<!-- write logs to file -->
|
||||
<target xsi:type="File" name="allfile" fileName="logs/nlog-all-${shortdate}.log"
|
||||
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${logger}|${uppercase:${level}}|${message} ${exception}" />
|
||||
|
||||
<!-- another file log, only own logs. Uses some ASP.NET core renderers -->
|
||||
<target xsi:type="File" name="ownFile" fileName="logs/nlog-own-${shortdate}.log"
|
||||
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${logger}|${uppercase:${level}}| ${message} ${exception}" />
|
||||
|
||||
<!-- write to the void aka just remove -->
|
||||
<target xsi:type="Null" name="blackhole" />
|
||||
</targets>
|
||||
|
||||
<!-- rules to map from logger name to target -->
|
||||
<rules>
|
||||
<!--All logs, including from Microsoft-->
|
||||
<logger name="*" minlevel="Trace" writeTo="allfile" />
|
||||
|
||||
<!--Skip Microsoft logs and so log only own logs-->
|
||||
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
|
||||
<logger name="*" minlevel="Information" writeTo="ownFile" />
|
||||
</rules>
|
||||
</nlog>
|
||||
Reference in New Issue
Block a user