diff --git a/dotnet-logging/LoggingAPI/LoggingAPI/Department.cs b/dotnet-logging/LoggingAPI/LoggingAPI/Department.cs index 66268786cc..9b2fc78238 100644 --- a/dotnet-logging/LoggingAPI/LoggingAPI/Department.cs +++ b/dotnet-logging/LoggingAPI/LoggingAPI/Department.cs @@ -1,26 +1,20 @@ -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.Extensions.Logging; -namespace LoggingAPI +namespace LoggingAPI; + +public class Department { - public class Department - { - public string Name { get; set; } - public string Description { get; set; } + public string Name { get; set; } + public string Description { get; set; } - private readonly ILogger _logger; - - public Department(string name, string description, ILoggerFactory factory) - { - Name = name; - Description = description; + private readonly ILogger _logger; + + public Department(string name, string description, ILoggerFactory factory) + { + Name = name; + Description = description; - _logger = factory.CreateLogger(); - _logger.LogInformation("Department is " + Name + " " + Description); - } + _logger = factory.CreateLogger(); + _logger.LogInformation("Department is {Name} {Description}", Name, Description); } } diff --git a/dotnet-logging/LoggingAPI/LoggingAPI/InMemoryLoggerProvider.cs b/dotnet-logging/LoggingAPI/LoggingAPI/InMemoryLoggerProvider.cs new file mode 100644 index 0000000000..d56a1d2bc9 --- /dev/null +++ b/dotnet-logging/LoggingAPI/LoggingAPI/InMemoryLoggerProvider.cs @@ -0,0 +1,28 @@ +using Microsoft.Extensions.Logging; + +namespace LoggingAPI; + +public sealed class InMemoryLoggerProvider : ILoggerProvider +{ + public List Messages { get; } = []; + + public ILogger CreateLogger(string categoryName) => new InMemoryLogger(categoryName, Messages); + + public void Dispose() { } +} + +public sealed class InMemoryLogger(string categoryName, List messages) : ILogger +{ + public IDisposable? BeginScope(TState state) where TState : notnull => null; + + public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None; + + public void Log(LogLevel logLevel, EventId eventId, TState state, + Exception? exception, Func formatter) + { + if (!IsEnabled(logLevel)) + return; + + messages.Add($"{logLevel}: {categoryName}: {formatter(state, exception)}"); + } +} diff --git a/dotnet-logging/LoggingAPI/LoggingAPI/LoggingAPI.csproj b/dotnet-logging/LoggingAPI/LoggingAPI/LoggingAPI.csproj index 4b6f8e0ede..91119fa3c8 100644 --- a/dotnet-logging/LoggingAPI/LoggingAPI/LoggingAPI.csproj +++ b/dotnet-logging/LoggingAPI/LoggingAPI/LoggingAPI.csproj @@ -2,16 +2,16 @@ Exe - net6.0 + net10.0 enable enable - - - - + + + + diff --git a/dotnet-logging/LoggingAPI/LoggingAPI/Program.cs b/dotnet-logging/LoggingAPI/LoggingAPI/Program.cs index 52a4209580..ec6bafe6e5 100644 --- a/dotnet-logging/LoggingAPI/LoggingAPI/Program.cs +++ b/dotnet-logging/LoggingAPI/LoggingAPI/Program.cs @@ -1,22 +1,13 @@ -using Microsoft.Extensions.Logging; +using LoggingAPI; +using Microsoft.Extensions.Logging; -namespace LoggingAPI +using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => { - public class Program - { - static void Main(string[] args) - { - ILoggerFactory loggerFactory = LoggerFactory.Create(builder => - { - builder.AddConsole(); - builder.AddDebug(); - }); + builder.AddConsole(); + builder.AddDebug(); +}); - ILogger logger = loggerFactory.CreateLogger(); - var student = new Student("John", "IT", logger); +ILogger logger = loggerFactory.CreateLogger(); +var student = new Student("John", "IT", logger); - var department = new Department("IT", "Information Technology", loggerFactory); - - } - } -} \ No newline at end of file +var department = new Department("IT", "Information Technology", loggerFactory); diff --git a/dotnet-logging/LoggingAPI/LoggingAPI/Student.cs b/dotnet-logging/LoggingAPI/LoggingAPI/Student.cs index 1ad10dd49d..845e0cc67f 100644 --- a/dotnet-logging/LoggingAPI/LoggingAPI/Student.cs +++ b/dotnet-logging/LoggingAPI/LoggingAPI/Student.cs @@ -1,26 +1,20 @@ -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.Extensions.Logging; -namespace LoggingAPI +namespace LoggingAPI; + +public class Student { - public class Student - { - public string Name { get; set; } - public string Department { get; set; } + public string Name { get; set; } + public string Department { get; set; } - private readonly ILogger _logger; + private readonly ILogger _logger; - public Student(string name, string department, ILogger logger) - { - Name = name; - Department = department; - _logger = logger; + public Student(string name, string department, ILogger logger) + { + Name = name; + Department = department; + _logger = logger; - _logger.LogInformation("Name of student is " + Name +" and his department is " + Department); - } + _logger.LogInformation("Name of student is {Name} and his department is {Department}", Name, Department); } } diff --git a/dotnet-logging/LoggingAPI/Tests/LoggingAPITests.cs b/dotnet-logging/LoggingAPI/Tests/LoggingAPITests.cs index a9c901eff5..60ea48b86e 100644 --- a/dotnet-logging/LoggingAPI/Tests/LoggingAPITests.cs +++ b/dotnet-logging/LoggingAPI/Tests/LoggingAPITests.cs @@ -1,31 +1,71 @@ using LoggingAPI; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; -using NSubstitute; -using System; -using System.IO; -namespace Tests +namespace Tests; + +[TestClass] +public class LoggingAPITests { - [TestClass] - public class LoggingAPITests + [TestMethod] + public void GivenLogger_ShouldLogInformation_WhenStudentIsCreated() { - [TestMethod] - public void GivenLogger_ShouldLogInformation_WhenStudentIsCreated() - { - ILogger logger = Substitute.For>(); - var student = new Student("John", "IT", logger); + var provider = new InMemoryLoggerProvider(); + using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddProvider(provider)); + + _ = new Student("John", "IT", factory.CreateLogger()); + + Assert.AreEqual( + "Information: LoggingAPI.Student: Name of student is John and his department is IT", + provider.Messages.Single()); + } - logger.Received(1).LogInformation("Name of student is John and his department is IT"); - } + [TestMethod] + public void GivenLoggerFactory_ShouldCreateLogger_WhenDepartmentIsCreated() + { + var provider = new InMemoryLoggerProvider(); + using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddProvider(provider)); + + _ = new Department("IT", "Information Technology", factory); + + Assert.AreEqual( + "Information: LoggingAPI.Department: Department is IT Information Technology", + provider.Messages.Single()); + } - [TestMethod] - public void GivenLoggerFactory_ShouldCreateLogger_WhenDepartmentIsCreated() + [TestMethod] + public void GivenMinimumLevelWarning_ShouldSkipInformation_WhenStudentIsCreated() + { + var provider = new InMemoryLoggerProvider(); + using ILoggerFactory factory = LoggerFactory.Create(builder => { - ILoggerFactory loggerFactory = Substitute.For(); - var department = new Department("IT", "Information Technology", loggerFactory); + builder.SetMinimumLevel(LogLevel.Warning); + builder.AddProvider(provider); + }); + + _ = new Student("John", "IT", factory.CreateLogger()); + + Assert.AreEqual(0, provider.Messages.Count); + } + + [TestMethod] + public void GivenHost_ShouldResolveTypedLogger_WhenStudentIsCreated() + { + var provider = new InMemoryLoggerProvider(); + + HostApplicationBuilder builder = Host.CreateApplicationBuilder(); + builder.Logging.ClearProviders(); + builder.Logging.AddProvider(provider); + + using IHost host = builder.Build(); + + ILogger logger = host.Services.GetRequiredService>(); + _ = new Student("John", "IT", logger); - loggerFactory.Received(1).CreateLogger(); - } + Assert.AreEqual( + "Information: LoggingAPI.Student: Name of student is John and his department is IT", + provider.Messages.Single()); } -} \ No newline at end of file +} diff --git a/dotnet-logging/LoggingAPI/Tests/Tests.csproj b/dotnet-logging/LoggingAPI/Tests/Tests.csproj index 81eea8b878..1f86fd9c5d 100644 --- a/dotnet-logging/LoggingAPI/Tests/Tests.csproj +++ b/dotnet-logging/LoggingAPI/Tests/Tests.csproj @@ -1,18 +1,18 @@ - net6.0 + net10.0 + enable enable - false - - - - - + + + + +