Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 14 additions & 20 deletions dotnet-logging/LoggingAPI/LoggingAPI/Department.cs
Original file line number Diff line number Diff line change
@@ -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<Department>();
_logger.LogInformation("Department is " + Name + " " + Description);
}
_logger = factory.CreateLogger<Department>();
_logger.LogInformation("Department is {Name} {Description}", Name, Description);
}
}
28 changes: 28 additions & 0 deletions dotnet-logging/LoggingAPI/LoggingAPI/InMemoryLoggerProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Microsoft.Extensions.Logging;

namespace LoggingAPI;

public sealed class InMemoryLoggerProvider : ILoggerProvider
{
public List<string> Messages { get; } = [];

public ILogger CreateLogger(string categoryName) => new InMemoryLogger(categoryName, Messages);

public void Dispose() { }
}

public sealed class InMemoryLogger(string categoryName, List<string> messages) : ILogger
{
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;

public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
return;

messages.Add($"{logLevel}: {categoryName}: {formatter(state, exception)}");
}
}
10 changes: 5 additions & 5 deletions dotnet-logging/LoggingAPI/LoggingAPI/LoggingAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.14" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.14" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.14" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.14" />
</ItemGroup>

</Project>
27 changes: 9 additions & 18 deletions dotnet-logging/LoggingAPI/LoggingAPI/Program.cs
Original file line number Diff line number Diff line change
@@ -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<Student> logger = loggerFactory.CreateLogger<Student>();
var student = new Student("John", "IT", logger);
ILogger<Student> logger = loggerFactory.CreateLogger<Student>();
var student = new Student("John", "IT", logger);

var department = new Department("IT", "Information Technology", loggerFactory);

}
}
}
var department = new Department("IT", "Information Technology", loggerFactory);
32 changes: 13 additions & 19 deletions dotnet-logging/LoggingAPI/LoggingAPI/Student.cs
Original file line number Diff line number Diff line change
@@ -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<Student> logger)
{
Name = name;
Department = department;
_logger = logger;
public Student(string name, string department, ILogger<Student> 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);
}
}
80 changes: 60 additions & 20 deletions dotnet-logging/LoggingAPI/Tests/LoggingAPITests.cs
Original file line number Diff line number Diff line change
@@ -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<Student> logger = Substitute.For<ILogger<Student>>();
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<Student>());

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<ILoggerFactory>();
var department = new Department("IT", "Information Technology", loggerFactory);
builder.SetMinimumLevel(LogLevel.Warning);
builder.AddProvider(provider);
});

_ = new Student("John", "IT", factory.CreateLogger<Student>());

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<Student> logger = host.Services.GetRequiredService<ILogger<Student>>();
_ = new Student("John", "IT", logger);

loggerFactory.Received(1).CreateLogger<Department>();
}
Assert.AreEqual(
"Information: LoggingAPI.Student: Name of student is John and his department is IT",
provider.Messages.Single());
}
}
}
14 changes: 7 additions & 7 deletions dotnet-logging/LoggingAPI/Tests/Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="NSubstitute" Version="4.2.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="4.5.2" />
<PackageReference Include="MSTest.TestFramework" Version="4.5.2" />
<PackageReference Include="coverlet.collector" Version="10.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.14" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading