From 8884d55380cc177234a6221cbe2a90161b1e7166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Sun, 13 Nov 2022 21:03:26 +0100 Subject: [PATCH] Code cleanup and enforce csharpier --- .csharpierrc | 6 + .filenesting.json | 3 + SmallInjector/Container.cs | 172 ++++++++++---------- SmallInjector/IContainer.cs | 88 +++++----- SmallInjector/SmallInjector.csproj | 9 +- SmallInjectorDemo.sln | 9 +- SmallInjectorDemo/Helper.cs | 63 ++++--- SmallInjectorDemo/Interfaces/IClock.cs | 19 +-- SmallInjectorDemo/Interfaces/IModule.cs | 15 +- SmallInjectorDemo/Interfaces/IServiceOne.cs | 14 +- SmallInjectorDemo/Interfaces/IServiceTwo.cs | 14 +- SmallInjectorDemo/Items/ModuleA.cs | 15 +- SmallInjectorDemo/Items/ModuleB.cs | 15 +- SmallInjectorDemo/Items/ModuleC.cs | 15 +- SmallInjectorDemo/Program.cs | 3 +- SmallInjectorDemo/ServiceConsumer.cs | 73 ++++----- SmallInjectorDemo/ServiceOne.cs | 41 +++-- SmallInjectorDemo/ServiceTwo.cs | 3 +- SmallInjectorDemo/SystemClock.cs | 16 +- 19 files changed, 281 insertions(+), 312 deletions(-) create mode 100644 .csharpierrc create mode 100644 .filenesting.json diff --git a/.csharpierrc b/.csharpierrc new file mode 100644 index 0000000..c01826a --- /dev/null +++ b/.csharpierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 200, + "useTabs": false, + "tabWidth": 4, + "preprocessorSymbolSets": ["", "DEBUG", "DEBUG,CODE_STYLE"] +} \ No newline at end of file diff --git a/.filenesting.json b/.filenesting.json new file mode 100644 index 0000000..0b71966 --- /dev/null +++ b/.filenesting.json @@ -0,0 +1,3 @@ +{ + "help":"https://go.microsoft.com/fwlink/?linkid=866610" +} \ No newline at end of file diff --git a/SmallInjector/Container.cs b/SmallInjector/Container.cs index 770f27a..c3f8f91 100644 --- a/SmallInjector/Container.cs +++ b/SmallInjector/Container.cs @@ -1,98 +1,90 @@ -using System; -using System.Collections.Generic; -using System.Linq; +namespace SmallInjector; -namespace SmallInjector +/// +/// A small dependency injector to demonstrate the pattern. +/// +public class Container : IContainer { - /// - /// A small dependency injector to demonstrate the pattern. - /// - public class Container : IContainer + private readonly Dictionary> _container = new(); + + /// + public void RegisterType(bool isSingleton, TService instance = default) where TService : TInterface { - private readonly Dictionary> _container = new Dictionary>(); - - /// - public void RegisterType(bool isSingleton, TService instance = default) - where TService : TInterface + if (!IsRegistered()) { - if (!IsRegistered()) - { - _container[typeof(TInterface)] = new List - {new RegisteredType(typeof(TService), isSingleton, null)}; - } - else - { - _container[typeof(TInterface)].Add(new RegisteredType(typeof(TService), isSingleton, null)); - } + _container[typeof(TInterface)] = new List { new RegisteredType(typeof(TService), isSingleton, null) }; } - - /// - public void RegisterType(bool isSingleton, TService instance = default) => - RegisterType(isSingleton, instance); - - /// - public TService Resolve() => (TService) Resolve(typeof(TService)); - - /// - public bool IsRegistered() => IsRegistered(typeof(TService)); - - /// - public bool IsRegistered(Type serviceType) => _container.ContainsKey(serviceType); - - /// - public IEnumerable ResolveAny(Type serviceType) + else { - if (!_container.TryGetValue(serviceType, out var registeredTypes)) - throw new Exception($"Dependency {serviceType.FullName} is not registered"); - foreach (var registeredType in registeredTypes) - { - if (registeredType.IsSingleton && registeredType.Instance != null) - { - yield return registeredType.Instance; - continue; - } - - var constructor = registeredType.ServiceType.GetConstructors()[0]; - var parameters = constructor.GetParameters(); - var constructorParameters = new object[parameters.Length]; - for (var i = 0; i < parameters.Length; i++) - { - var parameterType = parameters[i].ParameterType; - if (typeof(Array).IsAssignableFrom(parameterType)) - { - constructorParameters[i] = ResolveAny(parameterType.GetElementType()).ToArray(); - } - else - { - constructorParameters[i] = Resolve(parameters[i].ParameterType); - } - } - - var instance = constructor.Invoke(constructorParameters); - yield return registeredType.IsSingleton ? (registeredType.Instance = instance) : instance; - } - } - - /// - public IEnumerable ResolveAny() => ResolveAny(typeof(TService)); - - /// - public object Resolve(Type serviceType) => ResolveAny(serviceType).First(); - - private class RegisteredType - { - public bool IsSingleton { get; } - public Type ServiceType { get; } - public object Instance { get; set; } - - public RegisteredType(Type serviceType, bool isSingleton, object instance) - { - ServiceType = serviceType; - IsSingleton = isSingleton; - Instance = instance; - } - - public override string ToString() => ServiceType.ToString(); + _container[typeof(TInterface)].Add(new RegisteredType(typeof(TService), isSingleton, null)); } } -} \ No newline at end of file + + /// + public void RegisterType(bool isSingleton, TService instance = default) => RegisterType(isSingleton, instance); + + /// + public TService Resolve() => (TService)Resolve(typeof(TService)); + + /// + public bool IsRegistered() => IsRegistered(typeof(TService)); + + /// + public bool IsRegistered(Type serviceType) => _container.ContainsKey(serviceType); + + /// + public IEnumerable ResolveAny(Type serviceType) + { + if (!_container.TryGetValue(serviceType, out var registeredTypes)) + throw new Exception($"Dependency {serviceType.FullName} is not registered"); + foreach (var registeredType in registeredTypes) + { + if (registeredType.IsSingleton && registeredType.Instance != null) + { + yield return registeredType.Instance; + continue; + } + + var constructor = registeredType.ServiceType.GetConstructors()[0]; + var parameters = constructor.GetParameters(); + var constructorParameters = new object[parameters.Length]; + for (var i = 0; i < parameters.Length; i++) + { + var parameterType = parameters[i].ParameterType; + if (typeof(Array).IsAssignableFrom(parameterType)) + { + constructorParameters[i] = ResolveAny(parameterType.GetElementType()).ToArray(); + } + else + { + constructorParameters[i] = Resolve(parameters[i].ParameterType); + } + } + + var instance = constructor.Invoke(constructorParameters); + yield return registeredType.IsSingleton ? (registeredType.Instance = instance) : instance; + } + } + + /// + public IEnumerable ResolveAny() => ResolveAny(typeof(TService)); + + /// + public object Resolve(Type serviceType) => ResolveAny(serviceType).First(); + + private class RegisteredType + { + public bool IsSingleton { get; } + public Type ServiceType { get; } + public object Instance { get; set; } + + public RegisteredType(Type serviceType, bool isSingleton, object instance) + { + ServiceType = serviceType; + IsSingleton = isSingleton; + Instance = instance; + } + + public override string ToString() => ServiceType.ToString(); + } +} diff --git a/SmallInjector/IContainer.cs b/SmallInjector/IContainer.cs index 1ad361c..7ea09c7 100644 --- a/SmallInjector/IContainer.cs +++ b/SmallInjector/IContainer.cs @@ -1,55 +1,51 @@ -using System; -using System.Collections.Generic; +namespace SmallInjector; -namespace SmallInjector +/// +/// DI Container +/// +public interface IContainer { /// - /// DI Container + /// Register types in the resolve container. /// - public interface IContainer - { - /// - /// Register types in the resolve container. - /// - /// Type of the service. - /// Type of the interface of the service. - /// True if the service should be singleton. False otherwise. - /// instance of the service - void RegisterType(bool isSingleton, TService instance = default) where TService : TInterface; - - /// - /// Register types in the resolve container. - /// - void RegisterType(bool isSingleton, TService instance = default); + /// Type of the service. + /// Type of the interface of the service. + /// True if the service should be singleton. False otherwise. + /// instance of the service + void RegisterType(bool isSingleton, TService instance = default) where TService : TInterface; - /// - /// Resolve service of specified type. - /// - object Resolve(Type serviceType); + /// + /// Register types in the resolve container. + /// + void RegisterType(bool isSingleton, TService instance = default); - /// - /// Resolve service of specified type. - /// - TService Resolve(); + /// + /// Resolve service of specified type. + /// + object Resolve(Type serviceType); - /// - /// Returns true, if the service is registered. False otherwise. - /// - bool IsRegistered(); + /// + /// Resolve service of specified type. + /// + TService Resolve(); - /// - /// Returns true, if the service is registered. False otherwise. - /// - bool IsRegistered(Type serviceType); + /// + /// Returns true, if the service is registered. False otherwise. + /// + bool IsRegistered(); - /// - /// Resolve any implementation - /// - IEnumerable ResolveAny(Type serviceType); - - /// - /// Resolve any implementation - /// - IEnumerable ResolveAny(); - } -} \ No newline at end of file + /// + /// Returns true, if the service is registered. False otherwise. + /// + bool IsRegistered(Type serviceType); + + /// + /// Resolve any implementation + /// + IEnumerable ResolveAny(Type serviceType); + + /// + /// Resolve any implementation + /// + IEnumerable ResolveAny(); +} diff --git a/SmallInjector/SmallInjector.csproj b/SmallInjector/SmallInjector.csproj index 1a6f299..159ea73 100644 --- a/SmallInjector/SmallInjector.csproj +++ b/SmallInjector/SmallInjector.csproj @@ -1,8 +1,9 @@  - - netstandard2.0 - latest - + + netstandard2.0 + latest + enable + diff --git a/SmallInjectorDemo.sln b/SmallInjectorDemo.sln index 53d21c9..e393e30 100644 --- a/SmallInjectorDemo.sln +++ b/SmallInjectorDemo.sln @@ -1,12 +1,17 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29123.88 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33103.184 MinimumVisualStudioVersion = 15.0.26124.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SmallInjectorDemo", "SmallInjectorDemo\SmallInjectorDemo.csproj", "{620CC001-7DF9-4233-AFC2-187FD9144835}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SmallInjector", "SmallInjector\SmallInjector.csproj", "{8D52C856-A71D-4C50-832B-8679CDD030B4}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{97F8F459-C4B4-4C40-A4CA-2443A9C245D9}" + ProjectSection(SolutionItems) = preProject + .csharpierrc = .csharpierrc + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/SmallInjectorDemo/Helper.cs b/SmallInjectorDemo/Helper.cs index 7f98043..2765fd3 100644 --- a/SmallInjectorDemo/Helper.cs +++ b/SmallInjectorDemo/Helper.cs @@ -1,47 +1,44 @@ -using System; using System.Buffers.Text; -using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using SmallInjectorDemo.Interfaces; -namespace SmallInjectorDemo +namespace SmallInjectorDemo; + +/// +/// Static helper class for generating random numbers. +/// +public static class Helper { /// - /// Static helper class for generating random numbers. + /// Encode Base64 string /// - public static class Helper + public static string EncodeBase64String(this Guid guid) { - /// - /// Encode Base64 string - /// - public static string EncodeBase64String(this Guid guid) - { - Span guidBytes = stackalloc byte[16]; - Span encodedBytes = stackalloc byte[24]; + Span guidBytes = stackalloc byte[16]; + Span encodedBytes = stackalloc byte[24]; - MemoryMarshal.TryWrite(guidBytes, ref guid); // write bytes from the Guid - Base64.EncodeToUtf8(guidBytes, encodedBytes, out _, out _); + MemoryMarshal.TryWrite(guidBytes, ref guid); // write bytes from the Guid + Base64.EncodeToUtf8(guidBytes, encodedBytes, out _, out _); - // skip the last two bytes as these will be '==' padding - var final = Encoding.UTF8.GetString(encodedBytes.Slice(0, 22)); + // skip the last two bytes as these will be '==' padding + var final = Encoding.UTF8.GetString(encodedBytes.Slice(0, 22)); - return final; - } - - /// - /// Write method string. - /// - /// The current clock - /// id of the object - /// member name - /// file path - /// - public static string WriteMethodString(IClock clock, string id, [CallerMemberName] string memberName = null, [CallerFilePath] string filepath = null) - { - var classname = Path.GetFileNameWithoutExtension(filepath); - return $"[{clock.CurrentDateTime}] {classname}.{memberName?.TrimStart('.')}".PadRight(30) + $"Id: {id}"; - } + return final; } -} \ No newline at end of file + + /// + /// Write method string. + /// + /// The current clock + /// id of the object + /// member name + /// file path + /// + public static string WriteMethodString(IClock clock, string id, [CallerMemberName] string memberName = null, [CallerFilePath] string filepath = null) + { + var classname = Path.GetFileNameWithoutExtension(filepath); + return $"[{clock.CurrentDateTime}] {classname}.{memberName?.TrimStart('.')}".PadRight(30) + $"Id: {id}"; + } +} diff --git a/SmallInjectorDemo/Interfaces/IClock.cs b/SmallInjectorDemo/Interfaces/IClock.cs index 535fbc2..369b831 100644 --- a/SmallInjectorDemo/Interfaces/IClock.cs +++ b/SmallInjectorDemo/Interfaces/IClock.cs @@ -1,13 +1,12 @@ -namespace SmallInjectorDemo.Interfaces +namespace SmallInjectorDemo.Interfaces; + +/// +/// Interface of the clock. +/// +public interface IClock { /// - /// Interface of the clock. + /// Current Date-Time. /// - public interface IClock - { - /// - /// Current Date-Time. - /// - string CurrentDateTime { get; } - } -} \ No newline at end of file + string CurrentDateTime { get; } +} diff --git a/SmallInjectorDemo/Interfaces/IModule.cs b/SmallInjectorDemo/Interfaces/IModule.cs index 051156d..a08ef9c 100644 --- a/SmallInjectorDemo/Interfaces/IModule.cs +++ b/SmallInjectorDemo/Interfaces/IModule.cs @@ -1,9 +1,6 @@ -namespace SmallInjectorDemo.Interfaces -{ - /// - /// Defines the - /// - public interface IModule - { - } -} +namespace SmallInjectorDemo.Interfaces; + +/// +/// Defines the +/// +public interface IModule { } diff --git a/SmallInjectorDemo/Interfaces/IServiceOne.cs b/SmallInjectorDemo/Interfaces/IServiceOne.cs index eb1e4b8..8c87d69 100644 --- a/SmallInjectorDemo/Interfaces/IServiceOne.cs +++ b/SmallInjectorDemo/Interfaces/IServiceOne.cs @@ -1,10 +1,6 @@ -namespace SmallInjectorDemo.Interfaces -{ - /// - /// Interface for service one. - /// - public interface IServiceOne - { +namespace SmallInjectorDemo.Interfaces; - } -} \ No newline at end of file +/// +/// Interface for service one. +/// +public interface IServiceOne { } diff --git a/SmallInjectorDemo/Interfaces/IServiceTwo.cs b/SmallInjectorDemo/Interfaces/IServiceTwo.cs index d333dea..2e0570b 100644 --- a/SmallInjectorDemo/Interfaces/IServiceTwo.cs +++ b/SmallInjectorDemo/Interfaces/IServiceTwo.cs @@ -1,10 +1,6 @@ -namespace SmallInjectorDemo.Interfaces -{ - /// - /// Interface for service two. - /// - public interface IServiceTwo - { +namespace SmallInjectorDemo.Interfaces; - } -} \ No newline at end of file +/// +/// Interface for service two. +/// +public interface IServiceTwo { } diff --git a/SmallInjectorDemo/Items/ModuleA.cs b/SmallInjectorDemo/Items/ModuleA.cs index 5dc5d43..86a66bd 100644 --- a/SmallInjectorDemo/Items/ModuleA.cs +++ b/SmallInjectorDemo/Items/ModuleA.cs @@ -1,11 +1,8 @@ using SmallInjectorDemo.Interfaces; -namespace SmallInjectorDemo.Items -{ - /// - /// Defines the - /// - public class ModuleA : IModule - { - } -} +namespace SmallInjectorDemo.Items; + +/// +/// Defines the +/// +public class ModuleA : IModule { } diff --git a/SmallInjectorDemo/Items/ModuleB.cs b/SmallInjectorDemo/Items/ModuleB.cs index 8d96701..eb6cefd 100644 --- a/SmallInjectorDemo/Items/ModuleB.cs +++ b/SmallInjectorDemo/Items/ModuleB.cs @@ -1,11 +1,8 @@ using SmallInjectorDemo.Interfaces; -namespace SmallInjectorDemo.Items -{ - /// - /// Defines the - /// - public class ModuleB : IModule - { - } -} +namespace SmallInjectorDemo.Items; + +/// +/// Defines the +/// +public class ModuleB : IModule { } diff --git a/SmallInjectorDemo/Items/ModuleC.cs b/SmallInjectorDemo/Items/ModuleC.cs index 6fecea8..617a1ab 100644 --- a/SmallInjectorDemo/Items/ModuleC.cs +++ b/SmallInjectorDemo/Items/ModuleC.cs @@ -1,11 +1,8 @@ using SmallInjectorDemo.Interfaces; -namespace SmallInjectorDemo.Items -{ - /// - /// Defines the - /// - public class ModuleC : IModule - { - } -} +namespace SmallInjectorDemo.Items; + +/// +/// Defines the +/// +public class ModuleC : IModule { } diff --git a/SmallInjectorDemo/Program.cs b/SmallInjectorDemo/Program.cs index 1bb1424..c24b9b7 100644 --- a/SmallInjectorDemo/Program.cs +++ b/SmallInjectorDemo/Program.cs @@ -19,7 +19,6 @@ container.RegisterType(true); container.RegisterType(true); container.RegisterType(true); - Console.WriteLine(); Console.WriteLine("Check registrations:"); Console.WriteLine(nameof(IClock).PadRight(20) + container.IsRegistered()); @@ -38,4 +37,4 @@ useful1.TestTheServices(); Console.WriteLine(); useful2.TestTheServices(); Console.WriteLine(); -useful3.TestTheServices(); \ No newline at end of file +useful3.TestTheServices(); diff --git a/SmallInjectorDemo/ServiceConsumer.cs b/SmallInjectorDemo/ServiceConsumer.cs index 390a089..6c06b86 100644 --- a/SmallInjectorDemo/ServiceConsumer.cs +++ b/SmallInjectorDemo/ServiceConsumer.cs @@ -1,45 +1,42 @@ -using System; using SmallInjectorDemo.Interfaces; -namespace SmallInjectorDemo +namespace SmallInjectorDemo; + +/// +/// A very useful class. +/// +public class ServiceConsumer { + private readonly IClock _clock; + private readonly IServiceOne _service1; + private readonly IServiceTwo _service2; + private readonly string _id; + /// - /// A very useful class. + /// Creates a new instance of . /// - public class ServiceConsumer + /// The current clock + /// injected service one. + /// injected service two. + public ServiceConsumer(IClock clock, IServiceOne service1, IServiceTwo service2) { - private readonly IClock _clock; - private readonly IServiceOne _service1; - private readonly IServiceTwo _service2; - private readonly string _id; - - /// - /// Creates a new instance of . - /// - /// The current clock - /// injected service one. - /// injected service two. - public ServiceConsumer(IClock clock, IServiceOne service1, IServiceTwo service2) - { - _clock = clock; - _service1 = service1; - _service2 = service2; - _id = Guid.NewGuid().EncodeBase64String(); - Console.WriteLine(Helper.WriteMethodString(clock, _id)); - } - - /// - /// Test the injected services. - /// - public void TestTheServices() - { - Console.WriteLine(ToString()); - Console.WriteLine(_service1.ToString()); - Console.WriteLine(_service2.ToString()); - } - - /// - public override string ToString() => Helper.WriteMethodString(_clock, _id); - + _clock = clock; + _service1 = service1; + _service2 = service2; + _id = Guid.NewGuid().EncodeBase64String(); + Console.WriteLine(Helper.WriteMethodString(clock, _id)); } -} \ No newline at end of file + + /// + /// Test the injected services. + /// + public void TestTheServices() + { + Console.WriteLine(ToString()); + Console.WriteLine(_service1.ToString()); + Console.WriteLine(_service2.ToString()); + } + + /// + public override string ToString() => Helper.WriteMethodString(_clock, _id); +} diff --git a/SmallInjectorDemo/ServiceOne.cs b/SmallInjectorDemo/ServiceOne.cs index df4f53a..cb3441b 100644 --- a/SmallInjectorDemo/ServiceOne.cs +++ b/SmallInjectorDemo/ServiceOne.cs @@ -1,29 +1,26 @@ -using System; -using System.Collections.Generic; using SmallInjectorDemo.Interfaces; -namespace SmallInjectorDemo +namespace SmallInjectorDemo; + +/// +/// +/// Implementation of . +/// +public class ServiceOne : IServiceOne { - /// + private readonly IClock _clock; + private readonly string _id; + /// - /// Implementation of . + /// Creates a new instance of . /// - public class ServiceOne : IServiceOne + public ServiceOne(IClock clock) { - private readonly IClock _clock; - private readonly string _id; - - /// - /// Creates a new instance of . - /// - public ServiceOne(IClock clock, IModule[] modules) - { - _clock = clock; - _id = Guid.NewGuid().EncodeBase64String(); - Console.WriteLine(Helper.WriteMethodString(clock, _id)); - } - - /// - public override string ToString() => Helper.WriteMethodString(_clock, _id); + _clock = clock; + _id = Guid.NewGuid().EncodeBase64String(); + Console.WriteLine(Helper.WriteMethodString(clock, _id)); } -} \ No newline at end of file + + /// + public override string ToString() => Helper.WriteMethodString(_clock, _id); +} diff --git a/SmallInjectorDemo/ServiceTwo.cs b/SmallInjectorDemo/ServiceTwo.cs index 081c6a8..50e5169 100644 --- a/SmallInjectorDemo/ServiceTwo.cs +++ b/SmallInjectorDemo/ServiceTwo.cs @@ -1,4 +1,3 @@ -using System; using SmallInjectorDemo.Interfaces; namespace SmallInjectorDemo; @@ -24,4 +23,4 @@ public class ServiceTwo : IServiceTwo /// public override string ToString() => Helper.WriteMethodString(_clock, _id); -} \ No newline at end of file +} diff --git a/SmallInjectorDemo/SystemClock.cs b/SmallInjectorDemo/SystemClock.cs index b2375aa..5190bd1 100644 --- a/SmallInjectorDemo/SystemClock.cs +++ b/SmallInjectorDemo/SystemClock.cs @@ -1,12 +1,10 @@ -using System; -using SmallInjectorDemo.Interfaces; +using SmallInjectorDemo.Interfaces; -namespace SmallInjectorDemo +namespace SmallInjectorDemo; + +/// +public class SystemClock : IClock { /// - public class SystemClock : IClock - { - /// - public string CurrentDateTime => DateTime.Now.ToString("O"); - } -} \ No newline at end of file + public string CurrentDateTime => DateTime.Now.ToString("O"); +}