diff --git a/TJC.Singleton.Tests/Mocks/Logging/MockLogger.cs b/TJC.Singleton.Tests/Mocks/Logging/MockLogger.cs new file mode 100644 index 0000000..ccea8d8 --- /dev/null +++ b/TJC.Singleton.Tests/Mocks/Logging/MockLogger.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.Logging; + +namespace TJC.Singleton.Tests.Mocks.Logging; + +internal class MockLogger : ILogger +{ + public static MockLogger Default => new(); + + public IDisposable? BeginScope(TState state) + where TState : notnull => default!; + + public bool IsEnabled(LogLevel logLevel) => true; + + public void Log( + LogLevel logLevel, + EventId eventId, + TState state, + Exception? exception, + Func formatter + ) + { + Trace.WriteLine($"[{logLevel}:{eventId}] {formatter(state, exception)}"); + } +} diff --git a/TJC.Singleton.Tests/Tests/Instantiated/IsInstantiatedTest.cs b/TJC.Singleton.Tests/Tests/Instantiated/IsInstantiatedTest.cs index 4af25d0..7fd86bc 100644 --- a/TJC.Singleton.Tests/Tests/Instantiated/IsInstantiatedTest.cs +++ b/TJC.Singleton.Tests/Tests/Instantiated/IsInstantiatedTest.cs @@ -1,4 +1,5 @@ using TJC.Singleton.Factories; +using TJC.Singleton.Tests.Mocks.Logging; namespace TJC.Singleton.Tests.Tests.Instantiated; @@ -13,7 +14,7 @@ public void SingletonGetInstantiatedAfterBeingReferencedTest() MockSingletonInstantiated.IsInstantiated, $"{nameof(MockSingletonInstantiated)} was already instantiated" ); - SingletonFactory.InstantiateAll(trace: true); + SingletonFactory.InstantiateAll(MockLogger.Default); Assert.IsTrue( MockSingletonInstantiated.IsInstantiated, $"{nameof(MockSingletonInstantiated)} is not instantiated" diff --git a/TJC.Singleton/Factories/SingletonFactory.cs b/TJC.Singleton/Factories/SingletonFactory.cs index 7364266..d6e6875 100644 --- a/TJC.Singleton/Factories/SingletonFactory.cs +++ b/TJC.Singleton/Factories/SingletonFactory.cs @@ -1,9 +1,12 @@ -using System.Diagnostics; -using System.Reflection; +using System.Reflection; +using Microsoft.Extensions.Logging; using TJC.Singleton.Helpers; namespace TJC.Singleton.Factories; +/// +/// Factory for creating 's. +/// public static class SingletonFactory { #region Constants @@ -17,19 +20,23 @@ private class PlaceholderSingleton : SingletonBase; /// /// Instantiate all singletons in the current app domain. /// - /// /// + /// + /// /// - public static void InstantiateAll(bool trace = true, bool throwIfFailed = false) + public static void InstantiateAll( + ILogger? logger = null, + LogLevel logLevel = LogLevel.Trace, + bool throwIfFailed = false + ) { var failedToInstantiate = new List(); var singletons = GetSingletonTypes(); - if (trace) - Trace.WriteLine($"{singletons.Count} Singletons Found"); + logger?.Log(logLevel, "{count} Singletons Found", singletons.Count); foreach (var singleton in singletons) - if (!singleton.Instantiate(trace)) + if (!singleton.Instantiate(logger, logLevel)) failedToInstantiate.Add(singleton.Name); if (throwIfFailed && failedToInstantiate.Count > 0) @@ -63,34 +70,42 @@ public static List GetSingletonTypes() } /// - /// Instantiates a singleton of type . + /// Instantiates a singleton of type . /// /// - /// + /// + /// /// - public static bool Instantiate(bool trace) => Instantiate(typeof(T), trace); + public static bool Instantiate(ILogger? logger = null, LogLevel logLevel = LogLevel.Trace) => + Instantiate(typeof(T), logger, logLevel); /// /// Instantiates a singleton of given type. /// /// - /// + /// + /// /// /// - private static bool Instantiate(this Type singleton, bool trace) + private static bool Instantiate( + this Type singleton, + ILogger? logger = null, + LogLevel logLevel = LogLevel.Trace + ) { - if (trace) - Trace.WriteLine($"[{singleton.Name}] Instantiating"); + logger?.Log(logLevel, "[{name}] Instantiating", singleton.Name); var instanceProp = singleton.GetProperty( InstanceName, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy ) ?? throw new Exception($"[{singleton.Name}] does not have property [{InstanceName}]"); var instanceValue = instanceProp.GetValue(singleton); - if (trace) - Trace.WriteLine( - $"[{singleton.Name}] {(instanceValue != null ? "Instantiated" : "Failed to Instantiate")}" - ); + logger?.Log( + logLevel, + "[{name}] {result}", + singleton.Name, + instanceValue != null ? "Instantiated" : "Failed to Instantiate" + ); return instanceValue != null; } } diff --git a/TJC.Singleton/Helpers/SingletonConstructorHelpers.cs b/TJC.Singleton/Helpers/SingletonConstructorHelpers.cs index f32fd24..7cff52c 100644 --- a/TJC.Singleton/Helpers/SingletonConstructorHelpers.cs +++ b/TJC.Singleton/Helpers/SingletonConstructorHelpers.cs @@ -3,12 +3,15 @@ namespace TJC.Singleton.Helpers; +/// +/// Helpers for constructing . +/// public static class SingletonConstructorHelpers { #region Get Singlet Constructor /// - /// Gets the singleton constructor for the type . + /// Gets the singleton constructor for the type . /// /// /// @@ -45,7 +48,7 @@ public static ConstructorInfo GetSingletonConstructor(Type type) #region Check if Singleton has Valid Constructor /// - /// Checks if a singleton of type has a valid constructor. + /// Checks if a singleton of type . has a valid constructor. /// /// /// diff --git a/TJC.Singleton/Helpers/SingletonIdentifierHelpers.cs b/TJC.Singleton/Helpers/SingletonIdentifierHelpers.cs index 136e2ba..6b938e5 100644 --- a/TJC.Singleton/Helpers/SingletonIdentifierHelpers.cs +++ b/TJC.Singleton/Helpers/SingletonIdentifierHelpers.cs @@ -1,5 +1,8 @@ namespace TJC.Singleton.Helpers; +/// +/// Helpers for identifying details about . +/// public static class SingletonIdentifierHelpers { /// diff --git a/TJC.Singleton/SingletonBase.cs b/TJC.Singleton/SingletonBase.cs index 810bcae..35016e1 100644 --- a/TJC.Singleton/SingletonBase.cs +++ b/TJC.Singleton/SingletonBase.cs @@ -4,7 +4,7 @@ namespace TJC.Singleton; /// -/// Creates a single instance of that can be accessed through the property. +/// Creates a single instance of that can be accessed through the property. /// /// /// Must have a non-public parameterless constructor. diff --git a/TJC.Singleton/TJC.Singleton.csproj b/TJC.Singleton/TJC.Singleton.csproj index 9db1292..455c350 100644 --- a/TJC.Singleton/TJC.Singleton.csproj +++ b/TJC.Singleton/TJC.Singleton.csproj @@ -8,11 +8,11 @@ Singleton Base & Singleton Factory Tyler Carrol README.md - LICENSE + LICENSE $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/../CHANGELOG.md")) https://github.com/TJC-Tools/TJC.Singleton true - + @@ -31,20 +31,24 @@ True \ - + - - - <_Parameter1>TJC.Singleton.Tests + + + - + @@ -52,13 +56,17 @@ - - + @@ -66,18 +74,18 @@ - - + @@ -99,6 +107,11 @@ - +