From 800a06fc5a70636826ec13ef83bf9add4d137f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Sun, 28 Jul 2019 15:01:39 +0200 Subject: [PATCH] Playing with CommonServiceLocator --- SmallInjector/Container.cs | 55 +++++++++++++++------- SmallInjector/IContainer.cs | 6 ++- SmallInjector/ServiceLocatorWrapper.cs | 27 +++++++++++ SmallInjector/SmallInjector.csproj | 4 ++ SmallInjectorDemo/Program.cs | 15 ++++-- SmallInjectorDemo/SmallInjectorDemo.csproj | 3 ++ 6 files changed, 88 insertions(+), 22 deletions(-) create mode 100644 SmallInjector/ServiceLocatorWrapper.cs diff --git a/SmallInjector/Container.cs b/SmallInjector/Container.cs index 62727bb..0fdc9b1 100644 --- a/SmallInjector/Container.cs +++ b/SmallInjector/Container.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace SmallInjector { @@ -8,13 +9,21 @@ namespace SmallInjector /// public class Container : IContainer { - private readonly Dictionary _container = new Dictionary(); + private readonly Dictionary> _container = new Dictionary>(); /// public void RegisterType(bool isSingleton, TService instance = default) where TService : TInterface { - _container.Add(typeof(TInterface), new RegisteredType(typeof(TService), isSingleton, null)); + if (!IsRegistered()) + { + _container[typeof(TInterface)] = new List + {new RegisteredType(typeof(TService), isSingleton, null)}; + } + else + { + _container[typeof(TInterface)].Add(new RegisteredType(typeof(TService), isSingleton, null)); + } } /// @@ -30,26 +39,38 @@ namespace SmallInjector /// public bool IsRegistered(Type serviceType) => _container.ContainsKey(serviceType); - /// - public object Resolve(Type serviceInterface) + /// + public IEnumerable ResolveAny(Type serviceType) { - if (!_container.TryGetValue(serviceInterface, out var registeredType)) - throw new Exception(@"Dependency {serviceInterface} is not registered"); - - if (registeredType.IsSingleton && registeredType.Instance != null) - return registeredType.Instance; - var constructor = registeredType.ServiceType.GetConstructors()[0]; - var parameters = constructor.GetParameters(); - var constructorParameters = new object[parameters.Length]; - for (var i = 0; i < parameters.Length; i++) + if (!_container.TryGetValue(serviceType, out var registeredTypes)) + throw new Exception(@"Dependency {serviceType} is not registered"); + foreach (var registeredType in registeredTypes) { - constructorParameters[i] = Resolve(parameters[i].ParameterType); - } + if (registeredType.IsSingleton && registeredType.Instance != null) + { + yield return registeredType.Instance; + continue; + } - var instance = constructor.Invoke(constructorParameters); - return registeredType.IsSingleton ? (registeredType.Instance = instance) : instance; + var constructor = registeredType.ServiceType.GetConstructors()[0]; + var parameters = constructor.GetParameters(); + var constructorParameters = new object[parameters.Length]; + for (var i = 0; i < parameters.Length; i++) + { + 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; } diff --git a/SmallInjector/IContainer.cs b/SmallInjector/IContainer.cs index f2d765c..ad4eb8a 100644 --- a/SmallInjector/IContainer.cs +++ b/SmallInjector/IContainer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace SmallInjector { @@ -24,7 +25,7 @@ namespace SmallInjector /// /// Resolve service of specified type. /// - object Resolve(Type serviceInterface); + object Resolve(Type serviceType); /// /// Resolve service of specified type. @@ -40,5 +41,8 @@ namespace SmallInjector /// Returns true, if the service is registered. False otherwise. /// bool IsRegistered(Type serviceType); + + IEnumerable ResolveAny(Type serviceType); + IEnumerable ResolveAny(); } } \ No newline at end of file diff --git a/SmallInjector/ServiceLocatorWrapper.cs b/SmallInjector/ServiceLocatorWrapper.cs new file mode 100644 index 0000000..fb6b830 --- /dev/null +++ b/SmallInjector/ServiceLocatorWrapper.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace SmallInjector +{ + /// + /// Wrapper for Service Locator + /// + public class ServiceLocatorWrapper : CommonServiceLocator.ServiceLocatorImplBase + { + private readonly IContainer _container; + + /// + /// Creates new instance + /// + public ServiceLocatorWrapper(IContainer container) + { + _container = container; + } + + /// + protected override object DoGetInstance(Type serviceType, string key) => _container.Resolve(serviceType); + + /// + protected override IEnumerable DoGetAllInstances(Type serviceType) => _container.ResolveAny(serviceType); + } +} \ No newline at end of file diff --git a/SmallInjector/SmallInjector.csproj b/SmallInjector/SmallInjector.csproj index ef6f447..dc01571 100644 --- a/SmallInjector/SmallInjector.csproj +++ b/SmallInjector/SmallInjector.csproj @@ -12,4 +12,8 @@ C:\Users\Holger\Desktop\SmallInjectorDemo\SmallInjector\SmallInjector.xml + + + + diff --git a/SmallInjectorDemo/Program.cs b/SmallInjectorDemo/Program.cs index 650ae1d..1df59f7 100644 --- a/SmallInjectorDemo/Program.cs +++ b/SmallInjectorDemo/Program.cs @@ -1,4 +1,5 @@ using System; +using CommonServiceLocator; using SmallInjector; namespace SmallInjectorDemo @@ -7,8 +8,11 @@ namespace SmallInjectorDemo { private static void Main() { - Console.WriteLine("Small dependency injection example"); + IContainer container = new Container(); + ServiceLocator.SetLocatorProvider(() => new ServiceLocatorWrapper(container)); + + Console.WriteLine("Small dependency injection example"); container.RegisterType(true, container); Console.WriteLine("Register " + nameof(SystemClock)); container.RegisterType(true); @@ -28,9 +32,12 @@ namespace SmallInjectorDemo Console.WriteLine(); Console.WriteLine("Resolve class instances:"); - var useful1 = container.Resolve(); - var useful2 = container.Resolve(); - var useful3 = container.Resolve(); + //var useful1 = container.Resolve(); + //var useful2 = container.Resolve(); + //var useful3 = container.Resolve(); + var useful1 = ServiceLocator.Current.GetInstance(); + var useful2 = ServiceLocator.Current.GetInstance(); + var useful3 = ServiceLocator.Current.GetInstance(); Console.WriteLine(); Console.WriteLine("Run test methods:"); useful1.TestTheServices(); diff --git a/SmallInjectorDemo/SmallInjectorDemo.csproj b/SmallInjectorDemo/SmallInjectorDemo.csproj index 63e1361..9c116b3 100644 --- a/SmallInjectorDemo/SmallInjectorDemo.csproj +++ b/SmallInjectorDemo/SmallInjectorDemo.csproj @@ -12,6 +12,9 @@ bin\Release\netcoreapp2.1\SmallInjectorDemo.xml + + +