├── .gitignore ├── DotNet.DependencyInjectionBenchmarks.sln ├── LICENSE ├── README.md ├── docs ├── ArrayBenchmark.html ├── CreateScopeAndResolveBenchmark.html ├── EnumerableBenchmark.html ├── IEnumerableBenchmark.html ├── IReadOnlyListBenchmark.html ├── ImmutableCollectionBenchmark.html ├── LargeObjectBenchmark.html ├── LazyBenchmark.html ├── ListBenchmark.html ├── LookupBenchmark_0.html ├── LookupBenchmark_100.html ├── LookupBenchmark_2000.html ├── LookupBenchmark_50.html ├── LookupBenchmark_500.html ├── MetadataBenchmark.html ├── NoArgFactoryBenchmark.html ├── NoArgFuncBenchmark.html ├── OneArgFactoryBenchmark.html ├── OneArgFuncBenchmark.html ├── RegistrationBenchmark_100_ResolveAll.html ├── RegistrationBenchmark_100_ResolveHalf.html ├── RegistrationBenchmark_100_ResolveNone.html ├── RegistrationBenchmark_100_ResolveOne.html ├── RegistrationBenchmark_10_ResolveAll.html ├── RegistrationBenchmark_10_ResolveHalf.html ├── RegistrationBenchmark_10_ResolveNone.html ├── RegistrationBenchmark_10_ResolveOne.html ├── RegistrationBenchmark_500_ResolveAll.html ├── RegistrationBenchmark_500_ResolveHalf.html ├── RegistrationBenchmark_500_ResolveNone.html ├── RegistrationBenchmark_500_ResolveOne.html ├── SingletonBenchmark.html ├── SingletonPerAncestorBenchmark.html ├── SingletonPerObjectGraphBenchmark.html ├── SingletonPerScopeBenchmark.html ├── SmallObjectBenchmark.html ├── StronglyTypedMetadataBenchmark.html ├── ThreeArgFactoryBenchmark.html ├── ThreeArgFuncBenchmark.html └── index.html └── src └── DotNet.DependencyInjectionBenchmarks ├── BenchmarkConfig.cs ├── Benchmarks ├── BaseBenchmark.cs ├── Collections │ ├── ArrayBenchmark.cs │ ├── IEnumerableBenchmark.cs │ ├── IReadOnlyListBenchmark.cs │ ├── ImmutableCollectionBenchmark.cs │ └── ListBenchmark.cs ├── Factory │ ├── NoArgFactoryBenchmark.cs │ ├── OneArgFactoryBenchmark.cs │ └── ThreeArgFactoryBenchmark.cs ├── Func │ ├── NoArgFuncBenchmark.cs │ ├── OneArgFuncBenchmark.cs │ └── ThreeArgFuncBenchmark.cs ├── Lazy │ └── LazyBenchmark.cs ├── Lifestyles │ ├── SingletonPerAncestorBenchmark.cs │ ├── SingletonPerObjectGraphBenchmark.cs │ └── SingletonPerScopeBenchmark.cs ├── Lookup │ └── LookupBenchmark.cs ├── MemberInjection │ └── PropertyInjectionBenchmark.cs ├── Metadata │ ├── MetadataBenchmark.cs │ └── StronglyTypedMetadataBenchmark.cs ├── Registration │ └── RegistrationBenchmark.cs ├── Scoped │ └── CreateScopeAndResolveBenchmark.cs ├── Standard │ ├── EnumerableBenchmark.cs │ ├── GenericObjectBenchmark.cs │ ├── LargeObjectBenchmark.cs │ ├── SingletonBenchmark.cs │ └── SmallObjectBenchmark.cs └── StandardBenchmark.cs ├── Classes ├── DummyClasses.cs ├── EnumerableServices.cs ├── FieldInjectionClasses.cs ├── GenericObjectClasses.cs ├── ImportMultipleSmallObjectClasses.cs ├── LargeObjectClasses.cs ├── MetadataClasses.cs ├── MethodInjectionClasses.cs ├── OneArgClasses.cs ├── PropertyInjectionClasses.cs ├── SingletonService.cs ├── SmallObjectGraphService.cs ├── ThreeArgRefService.cs ├── ThreeArgService.cs └── TransientService.cs ├── Containers ├── AutofacContainer.cs ├── CastleWindsorContainer.cs ├── DryIocContainer.cs ├── GraceContainer.cs ├── IContainer.cs ├── LightInjectContainer.cs ├── MicrosoftDependencyInjectionContainer.cs ├── NInjectContainer.cs ├── SimpleInjectorContainer.cs └── StructureMapContainer.cs ├── DotNet.DependencyInjectionBenchmarks.csproj ├── Exporters ├── StreamWriterExtensions.cs └── WebSiteExporter.cs └── Program.cs /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /src/DotNet.DependencyInjectionBenchmarks/BenchmarkDotNet.Artifacts 6 | /src/DotNet.DependencyInjectionBenchmarks/bin 7 | /src/DotNet.DependencyInjectionBenchmarks/obj 8 | /.vs 9 | -------------------------------------------------------------------------------- /DotNet.DependencyInjectionBenchmarks.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.13 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet.DependencyInjectionBenchmarks", "src\DotNet.DependencyInjectionBenchmarks\DotNet.DependencyInjectionBenchmarks.csproj", "{E37BB527-D2CA-4545-8C09-C93C7CE1BCBC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {E37BB527-D2CA-4545-8C09-C93C7CE1BCBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {E37BB527-D2CA-4545-8C09-C93C7CE1BCBC}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {E37BB527-D2CA-4545-8C09-C93C7CE1BCBC}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {E37BB527-D2CA-4545-8C09-C93C7CE1BCBC}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ian Johnson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | Any results that are generated by the benchmark and published must be accurate and follow the spirit of the Benchmark. 16 | Sole discretion falls to Ian Johnson on if the results are accurate and follow the spirit. 17 | If asked by Ian Johnson the results must be removed from being publicly accessible. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DotNet.DependencyInjectionBenchmarks 2 | Benchmarks for .net dependency injection containers 3 | 4 | Published Results can be found [here](https://ipjohnson.github.io/DotNet.DependencyInjectionBenchmarks/) 5 | 6 | Note: PR's are welcome but if you are adding a new container please stay within the spirit of the tests. Daniel Palme has an excelent benchmark suite that can be found [here](https://github.com/danielpalme/IocPerformance) that has far more containers. 7 | -------------------------------------------------------------------------------- /docs/ImmutableCollectionBenchmark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 112 |
113 |
114 |

ImmutableCollection

115 |

This benchmark registers 5 small objects then resolves them as an ImmutableList(T). The code can be found here.

116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 |
ContainerEnvMean (ns)Median (ns)Max (ns)OutliersStd Dev (ns)Std Err (ns)Gen 1Gen 2Bytes Alloc
GraceClr527.3527.3527.400.0370.01100752
GraceCore723.9723.6727.201.8600.48000752
138 | 139 |
140 |
141 | Details 142 |
143 |

144 | BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
145 | Processor=Intel Core i7-3770 CPU 3.40GHz (Ivy Bridge), ProcessorCount=4
146 | Frequency=3320336 Hz, Resolution=301.1743 ns, Timer=TSC
147 |   [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
148 |   Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
149 |   Core   : .NET Core 4.6.25211.01, 64bit RyuJIT
150 | 
151 | 152 | 153 | 154 | 155 | 156 | 183 |
184 | 185 | -------------------------------------------------------------------------------- /docs/ListBenchmark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 112 |
113 |
114 |

List

115 |

This benchmark registers 5 small objects then resolves them as a List(T). The code can be found here.

116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |
ContainerEnvMean (ns)Median (ns)Max (ns)OutliersStd Dev (ns)Std Err (ns)Gen 1Gen 2Bytes Alloc
GraceClr294.6294.6294.700.0300.00800568
StructureMapClr7345.17345.07355.005.2671.360004896
GraceCore237.0236.9237.300.1510.03900568
StructureMapCore10239.210240.010244.705.2931.367004744
140 | 141 |
142 |
143 | Details 144 |
145 |

146 | BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
147 | Processor=Intel Core i7-3770 CPU 3.40GHz (Ivy Bridge), ProcessorCount=4
148 | Frequency=3320336 Hz, Resolution=301.1743 ns, Timer=TSC
149 |   [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
150 |   Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
151 |   Core   : .NET Core 4.6.25211.01, 64bit RyuJIT
152 | 
153 | 154 | 155 | 156 | 157 | 158 | 185 |
186 | 187 | -------------------------------------------------------------------------------- /docs/OneArgFuncBenchmark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 112 |
113 |
114 |

OneArgFunc

115 |

This benchmark registers a small object then resolves a one argument function for each object The code can be found here.

116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |
ContainerEnvMean (ns)Median (ns)Max (ns)OutliersStd Dev (ns)Std Err (ns)Gen 1Gen 2Bytes Alloc
DryIocClr72.072.072.000.0100.00300184
GraceClr183.7183.7183.800.0130.00300408
DryIocCore1882.71880.41889.504.6271.19500272
GraceCore196.4196.4196.420.0130.00400408
140 | 141 |
142 |
143 | Details 144 |
145 |

146 | BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
147 | Processor=Intel Core i7-3770 CPU 3.40GHz (Ivy Bridge), ProcessorCount=4
148 | Frequency=3320336 Hz, Resolution=301.1743 ns, Timer=TSC
149 |   [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
150 |   Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
151 |   Core   : .NET Core 4.6.25211.01, 64bit RyuJIT
152 | 
153 | 154 | 155 | 156 | 157 | 158 | 185 |
186 | 187 | -------------------------------------------------------------------------------- /docs/ThreeArgFuncBenchmark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 112 |
113 |
114 |

ThreeArgFunc

115 |

This benchmark registers a small object then resolves a three argument function for each object The code can be found here.

116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |
ContainerEnvMean (ns)Median (ns)Max (ns)OutliersStd Dev (ns)Std Err (ns)Gen 1Gen 2Bytes Alloc
DryIocClr39.839.839.810.0020.0010064
GraceClr449.9449.9450.100.0980.02500952
DryIocCore1163.61163.31166.402.0140.52000128
GraceCore466.6466.6466.700.0280.00700952
140 | 141 |
142 |
143 | Details 144 |
145 |

146 | BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
147 | Processor=Intel Core i7-3770 CPU 3.40GHz (Ivy Bridge), ProcessorCount=4
148 | Frequency=3320336 Hz, Resolution=301.1743 ns, Timer=TSC
149 |   [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
150 |   Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
151 |   Core   : .NET Core 4.6.25211.01, 64bit RyuJIT
152 | 
153 | 154 | 155 | 156 | 157 | 158 | 185 |
186 | 187 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/BenchmarkConfig.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Configs; 2 | using BenchmarkDotNet.Diagnosers; 3 | using BenchmarkDotNet.Exporters; 4 | using BenchmarkDotNet.Exporters.Csv; 5 | using BenchmarkDotNet.Exporters.Json; 6 | using BenchmarkDotNet.Jobs; 7 | using DotNet.DependencyInjectionBenchmarks.Exporters; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks 10 | { 11 | public class BenchmarkConfig : ManualConfig 12 | { 13 | public BenchmarkConfig() 14 | { 15 | Add(Job.Core, Job.Clr); 16 | Add(new MemoryDiagnoser()); 17 | Add(new CompositeExporter(JsonExporter.Full, new WebSiteExporter())); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/BaseBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using DotNet.DependencyInjectionBenchmarks.Classes; 5 | using DotNet.DependencyInjectionBenchmarks.Containers; 6 | 7 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks 8 | { 9 | public abstract class BaseBenchmark 10 | { 11 | public static readonly int ExtraRegistrationsCount = 200; 12 | public static readonly int ExtraRegistrationsResolveCount = ExtraRegistrationsCount / 4; 13 | 14 | protected IContainer AutofacContainer; 15 | protected IContainer CastleWindsorContainer; 16 | protected IContainer DryIocContainer; 17 | protected IContainer GraceContainer; 18 | protected IContainer LightInjectContainer; 19 | protected IContainer MicrosoftDependencyInjectionContainer; 20 | protected IContainer NInjectContainer; 21 | protected IContainer SimpleInjectorContainer; 22 | protected IContainer StructureMapContainer; 23 | 24 | protected IContainer CreateAutofacContainer() 25 | { 26 | return AutofacContainer = new AutofacContainer(); 27 | } 28 | 29 | protected IContainer CreateCastleWindsorContainer() 30 | { 31 | return CastleWindsorContainer = new CastleWindsorContainer(); 32 | } 33 | 34 | protected IContainer CreateDryIocContainer() 35 | { 36 | return DryIocContainer = new DryIocContainer(); 37 | } 38 | 39 | protected IContainer CreateGraceContainer() 40 | { 41 | return GraceContainer = new GraceContainer(); 42 | } 43 | 44 | protected IContainer CreateLightInjectContainer() 45 | { 46 | return LightInjectContainer = new LightInjectContainer(); 47 | } 48 | 49 | protected IContainer CreateMicrosoftDependencyInjectionContainer() 50 | { 51 | return MicrosoftDependencyInjectionContainer = new MicrosoftDependencyInjectionContainer(); 52 | } 53 | 54 | protected IContainer CreateNInjectContainer() 55 | { 56 | return NInjectContainer = new NInjectContainer(); 57 | } 58 | 59 | protected IContainer CreateSimpleInjectorContainer() 60 | { 61 | return SimpleInjectorContainer = new SimpleInjectorContainer(); 62 | } 63 | 64 | protected IContainer CreateStructureMapContainer() 65 | { 66 | return StructureMapContainer = new StructureMapContainer(); 67 | } 68 | 69 | /// 70 | /// Registers definitions and dummy classes for scope 71 | /// 72 | /// 73 | /// 74 | /// 75 | protected virtual void SetupContainerForTest(IContainer container, IEnumerable definitions, params Action[] resolveStatements) 76 | { 77 | var dummyTypes = DummyClasses.GetTypes(ExtraRegistrationsCount).ToArray(); 78 | 79 | container.Registration(dummyTypes.Select(t => new RegistrationDefinition { ExportType = t, ActivationType = t })); 80 | 81 | var definitionArray = definitions.ToArray(); 82 | 83 | container.Registration(definitionArray); 84 | 85 | container.BuildContainer(); 86 | 87 | var resolveTypes = new List(dummyTypes.Take(ExtraRegistrationsResolveCount)); 88 | 89 | if (resolveStatements != null && resolveStatements.Length > 0) 90 | { 91 | var gap = resolveTypes.Count / resolveStatements.Length; 92 | 93 | var index = gap / 2; 94 | 95 | for (var i = 0; i < resolveTypes.Count; i++) 96 | { 97 | if (index < resolveStatements.Length && i == index * gap) 98 | { 99 | resolveStatements[index](container); 100 | index++; 101 | } 102 | 103 | container.Resolve(resolveTypes[i]); 104 | } 105 | } 106 | else 107 | { 108 | var gap = resolveTypes.Count / definitionArray.Length; 109 | 110 | var index = gap / 2; 111 | 112 | foreach (var definition in definitionArray) 113 | { 114 | resolveTypes.Insert(index, definition.ExportType); 115 | 116 | index += gap + 1; 117 | } 118 | 119 | foreach (var resolveType in resolveTypes) 120 | { 121 | container.Resolve(resolveType); 122 | } 123 | } 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Collections/ArrayBenchmark.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using DotNet.DependencyInjectionBenchmarks.Classes; 3 | using DotNet.DependencyInjectionBenchmarks.Containers; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Collections 9 | { 10 | [BenchmarkCategory("Collections")] 11 | public class ArrayBenchmark : StandardBenchmark 12 | { 13 | public static string Description => 14 | "This benchmark registers 5 small objects then resolves them as an Array."; 15 | 16 | protected override IEnumerable Definitions => EnumerableServices.Definitions(); 17 | 18 | protected override void ExecuteBenchmark(IResolveScope scope) 19 | { 20 | if (scope.Resolve().Count() != 5) 21 | { 22 | throw new Exception("Count does not equal 5"); 23 | } 24 | } 25 | 26 | [Benchmark] 27 | [BenchmarkCategory(nameof(Autofac))] 28 | public void Autofac() 29 | { 30 | ExecuteBenchmark(AutofacContainer); 31 | } 32 | 33 | [Benchmark] 34 | [BenchmarkCategory(nameof(DryIoc))] 35 | public void DryIoc() 36 | { 37 | ExecuteBenchmark(DryIocContainer); 38 | } 39 | 40 | [Benchmark] 41 | [BenchmarkCategory(nameof(Grace))] 42 | public void Grace() 43 | { 44 | ExecuteBenchmark(GraceContainer); 45 | } 46 | 47 | [Benchmark] 48 | [BenchmarkCategory(nameof(LightInject))] 49 | public void LightInject() 50 | { 51 | ExecuteBenchmark(LightInjectContainer); 52 | } 53 | 54 | [Benchmark] 55 | [BenchmarkCategory(nameof(SimpleInjector))] 56 | public void SimpleInjector() 57 | { 58 | ExecuteBenchmark(SimpleInjectorContainer); 59 | } 60 | 61 | [Benchmark] 62 | [BenchmarkCategory(nameof(StructureMap))] 63 | public void StructureMap() 64 | { 65 | ExecuteBenchmark(StructureMapContainer); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Collections/IEnumerableBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Classes; 6 | using DotNet.DependencyInjectionBenchmarks.Containers; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Collections 9 | { 10 | [BenchmarkCategory("Collections")] 11 | public class IEnumerableBenchmark : StandardBenchmark 12 | { 13 | public static string Description => 14 | "This benchmark registers 5 small objects then resolves them as an IEnumerable(T)."; 15 | 16 | protected override IEnumerable Definitions => EnumerableServices.Definitions(); 17 | 18 | protected override void ExecuteBenchmark(IResolveScope scope) 19 | { 20 | if (scope.Resolve>().Count() != 5) 21 | { 22 | throw new Exception("Count does not equal 5"); 23 | } 24 | } 25 | 26 | [Benchmark] 27 | [BenchmarkCategory(nameof(Autofac))] 28 | public void Autofac() 29 | { 30 | ExecuteBenchmark(AutofacContainer); 31 | } 32 | 33 | [Benchmark] 34 | [BenchmarkCategory(nameof(DryIoc))] 35 | public void DryIoc() 36 | { 37 | ExecuteBenchmark(DryIocContainer); 38 | } 39 | 40 | [Benchmark] 41 | [BenchmarkCategory(nameof(Grace))] 42 | public void Grace() 43 | { 44 | ExecuteBenchmark(GraceContainer); 45 | } 46 | 47 | [Benchmark] 48 | [BenchmarkCategory(nameof(LightInject))] 49 | public void LightInject() 50 | { 51 | ExecuteBenchmark(LightInjectContainer); 52 | } 53 | 54 | [Benchmark] 55 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 56 | public void MicrosoftDependencyInjection() 57 | { 58 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 59 | } 60 | 61 | [Benchmark] 62 | [BenchmarkCategory(nameof(SimpleInjector))] 63 | public void SimpleInjector() 64 | { 65 | ExecuteBenchmark(SimpleInjectorContainer); 66 | } 67 | 68 | [Benchmark] 69 | [BenchmarkCategory(nameof(StructureMap))] 70 | public void StructureMap() 71 | { 72 | ExecuteBenchmark(StructureMapContainer); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Collections/IReadOnlyListBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Classes; 6 | using DotNet.DependencyInjectionBenchmarks.Containers; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Collections 9 | { 10 | [BenchmarkCategory("Collections")] 11 | public class IReadOnlyListBenchmark : StandardBenchmark 12 | { 13 | public static string Description => 14 | "This benchmark registers 5 small objects then resolves them as an IReadOnlyList(T)."; 15 | 16 | protected override IEnumerable Definitions => throw new NotImplementedException(); 17 | 18 | protected override void ExecuteBenchmark(IResolveScope scope) 19 | { 20 | if (scope.Resolve>().Count() != 5) 21 | { 22 | throw new Exception("Count does not equal 5"); 23 | } 24 | } 25 | 26 | [Benchmark] 27 | [BenchmarkCategory(nameof(Autofac))] 28 | public void Autofac() 29 | { 30 | ExecuteBenchmark(AutofacContainer); 31 | } 32 | 33 | [Benchmark] 34 | [BenchmarkCategory(nameof(DryIoc))] 35 | public void DryIoc() 36 | { 37 | ExecuteBenchmark(DryIocContainer); 38 | } 39 | 40 | [Benchmark] 41 | [BenchmarkCategory(nameof(Grace))] 42 | public void Grace() 43 | { 44 | ExecuteBenchmark(GraceContainer); 45 | } 46 | 47 | [Benchmark] 48 | [BenchmarkCategory(nameof(LightInject))] 49 | public void LightInject() 50 | { 51 | ExecuteBenchmark(LightInjectContainer); 52 | } 53 | 54 | [Benchmark] 55 | [BenchmarkCategory(nameof(SimpleInjector))] 56 | public void SimpleInjector() 57 | { 58 | ExecuteBenchmark(SimpleInjectorContainer); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Collections/ImmutableCollectionBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Immutable; 4 | using System.Linq; 5 | using BenchmarkDotNet.Attributes; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Collections 10 | { 11 | [BenchmarkCategory("Collections")] 12 | public class ImmutableCollectionBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | "This benchmark registers 5 small objects then resolves them as an ImmutableList(T)."; 16 | 17 | protected override IEnumerable Definitions => EnumerableServices.Definitions(); 18 | 19 | protected override void ExecuteBenchmark(IResolveScope scope) 20 | { 21 | if (scope.Resolve>().Count() != 5) 22 | { 23 | throw new Exception("Count does not equal 5"); 24 | } 25 | } 26 | 27 | [Benchmark] 28 | [BenchmarkCategory(nameof(Grace))] 29 | public void Grace() 30 | { 31 | ExecuteBenchmark(GraceContainer); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Collections/ListBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Classes; 6 | using DotNet.DependencyInjectionBenchmarks.Containers; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Collections 9 | { 10 | [BenchmarkCategory("Collections")] 11 | public class ListBenchmark : StandardBenchmark 12 | { 13 | public static string Description => 14 | "This benchmark registers 5 small objects then resolves them as a List(T)."; 15 | 16 | protected override IEnumerable Definitions => EnumerableServices.Definitions(); 17 | 18 | protected override void ExecuteBenchmark(IResolveScope scope) 19 | { 20 | if (scope.Resolve>().Count() != 5) 21 | { 22 | throw new Exception("Count does not equal 5"); 23 | } 24 | } 25 | 26 | [Benchmark] 27 | [BenchmarkCategory(nameof(Grace))] 28 | public void Grace() 29 | { 30 | ExecuteBenchmark(GraceContainer); 31 | } 32 | 33 | [Benchmark] 34 | [BenchmarkCategory(nameof(StructureMap))] 35 | public void StructureMap() 36 | { 37 | ExecuteBenchmark(StructureMapContainer); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Factory/NoArgFactoryBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Factory 10 | { 11 | [BenchmarkCategory("Factory")] 12 | public class NoArgFactoryBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | "This benchmark registers a small object using a factory to provide one piece of the object graph."; 16 | 17 | protected override void SetupContainerForTest(IContainer container, IEnumerable definitions, params Action[] resolveStatements) 18 | { 19 | container.RegisterFactory(() => new TransientService(), RegistrationMode.Single, RegistrationLifestyle.Transient); 20 | 21 | base.SetupContainerForTest(container, definitions, resolveStatements); 22 | } 23 | 24 | protected override IEnumerable Definitions 25 | { 26 | get 27 | { 28 | yield return new RegistrationDefinition { ExportType = typeof(ISmallObjectService), ActivationType = typeof(SmallObjectService) }; 29 | 30 | yield return new RegistrationDefinition { ExportType = typeof(ISingletonService), ActivationType = typeof(SingletonService), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 31 | } 32 | } 33 | 34 | protected override void ExecuteBenchmark(IResolveScope scope) 35 | { 36 | scope.Resolve(); 37 | } 38 | 39 | [Benchmark] 40 | [BenchmarkCategory(nameof(Autofac))] 41 | public void Autofac() 42 | { 43 | ExecuteBenchmark(AutofacContainer); 44 | } 45 | 46 | [Benchmark] 47 | [BenchmarkCategory(nameof(CastleWindsor))] 48 | public void CastleWindsor() 49 | { 50 | ExecuteBenchmark(CastleWindsorContainer); 51 | } 52 | 53 | [Benchmark] 54 | [BenchmarkCategory(nameof(DryIoc))] 55 | public void DryIoc() 56 | { 57 | ExecuteBenchmark(DryIocContainer); 58 | } 59 | 60 | [Benchmark] 61 | [BenchmarkCategory(nameof(Grace))] 62 | public void Grace() 63 | { 64 | ExecuteBenchmark(GraceContainer); 65 | } 66 | 67 | [Benchmark] 68 | [BenchmarkCategory(nameof(LightInject))] 69 | public void LightInject() 70 | { 71 | ExecuteBenchmark(LightInjectContainer); 72 | } 73 | 74 | [Benchmark] 75 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 76 | public void MicrosoftDependencyInjection() 77 | { 78 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 79 | } 80 | 81 | [Benchmark] 82 | [BenchmarkCategory(nameof(SimpleInjector))] 83 | public void SimpleInjector() 84 | { 85 | ExecuteBenchmark(SimpleInjectorContainer); 86 | } 87 | 88 | [Benchmark] 89 | [BenchmarkCategory(nameof(StructureMap))] 90 | public void StructureMap() 91 | { 92 | ExecuteBenchmark(StructureMapContainer); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Factory/OneArgFactoryBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Factory 10 | { 11 | [BenchmarkCategory("Factory")] 12 | public class OneArgFactoryBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | "This benchmark registers a small object graph and a one argument function to create part of the object graph"; 16 | 17 | protected override IEnumerable Definitions => SmallObjectServices.Definitions(); 18 | 19 | /// 20 | /// Registers definitions and dummy classes for scope 21 | /// 22 | /// 23 | /// 24 | /// 25 | protected override void SetupContainerForTest(IContainer container, IEnumerable definitions, params Action[] resolveStatements) 26 | { 27 | container.RegisterFactory(service => new OneArgeFactoryService(service), RegistrationMode.Single, RegistrationLifestyle.Transient); 28 | 29 | base.SetupContainerForTest(container, definitions, resolveStatements); 30 | } 31 | 32 | protected override void ExecuteBenchmark(IResolveScope scope) 33 | { 34 | scope.Resolve(typeof(IOneArgeFactoryService)); 35 | } 36 | 37 | [Benchmark] 38 | [BenchmarkCategory(nameof(Autofac))] 39 | public void Autofac() 40 | { 41 | ExecuteBenchmark(AutofacContainer); 42 | } 43 | 44 | [Benchmark] 45 | [BenchmarkCategory(nameof(CastleWindsor))] 46 | public void CastleWindsor() 47 | { 48 | ExecuteBenchmark(CastleWindsorContainer); 49 | } 50 | 51 | [Benchmark] 52 | [BenchmarkCategory(nameof(DryIoc))] 53 | public void DryIoc() 54 | { 55 | ExecuteBenchmark(DryIocContainer); 56 | } 57 | 58 | [Benchmark] 59 | [BenchmarkCategory(nameof(Grace))] 60 | public void Grace() 61 | { 62 | ExecuteBenchmark(GraceContainer); 63 | } 64 | 65 | [Benchmark] 66 | [BenchmarkCategory(nameof(LightInject))] 67 | public void LightInject() 68 | { 69 | ExecuteBenchmark(LightInjectContainer); 70 | } 71 | 72 | [Benchmark] 73 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 74 | public void MicrosoftDependencyInjection() 75 | { 76 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 77 | } 78 | 79 | [Benchmark] 80 | [BenchmarkCategory(nameof(StructureMap))] 81 | public void StructureMap() 82 | { 83 | ExecuteBenchmark(StructureMapContainer); 84 | } 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Factory/ThreeArgFactoryBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using BenchmarkDotNet.Attributes; 4 | using DotNet.DependencyInjectionBenchmarks.Classes; 5 | using DotNet.DependencyInjectionBenchmarks.Containers; 6 | 7 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Factory 8 | { 9 | [BenchmarkCategory("Factory")] 10 | public class ThreeArgFactoryBenchmark : StandardBenchmark 11 | { 12 | public static string Description => 13 | "This benchmark resolves a small object graph using a factory that takes 3 arguments."; 14 | 15 | /// 16 | /// Registers definitions and dummy classes for scope 17 | /// 18 | /// 19 | /// 20 | /// 21 | protected override void SetupContainerForTest(IContainer container, IEnumerable definitions, params Action[] resolveStatements) 22 | { 23 | container.RegisterFactory((transient1, transient2, transient3) => new ThreeArgRefService(transient1, transient2, transient3), RegistrationMode.Single, RegistrationLifestyle.Transient); 24 | 25 | base.SetupContainerForTest(container, definitions, scope => scope.Resolve(typeof(IThreeArgRefService))); 26 | } 27 | 28 | protected override IEnumerable Definitions => 29 | new[] 30 | { 31 | new RegistrationDefinition { ExportType = typeof(IThreeArgTransient1), ActivationType = typeof(ThreeArgTransient1) }, 32 | new RegistrationDefinition { ExportType = typeof(IThreeArgTransient2), ActivationType = typeof(ThreeArgTransient2) }, 33 | new RegistrationDefinition { ExportType = typeof(IThreeArgTransient3), ActivationType = typeof(ThreeArgTransient3) } 34 | }; 35 | 36 | protected override void ExecuteBenchmark(IResolveScope scope) 37 | { 38 | scope.Resolve(typeof(IThreeArgRefService)); 39 | } 40 | 41 | [Benchmark] 42 | [BenchmarkCategory(nameof(Autofac))] 43 | public void Autofac() 44 | { 45 | ExecuteBenchmark(AutofacContainer); 46 | } 47 | 48 | [Benchmark] 49 | [BenchmarkCategory(nameof(CastleWindsor))] 50 | public void CastleWindsor() 51 | { 52 | ExecuteBenchmark(CastleWindsorContainer); 53 | } 54 | 55 | [Benchmark] 56 | [BenchmarkCategory(nameof(DryIoc))] 57 | public void DryIoc() 58 | { 59 | ExecuteBenchmark(DryIocContainer); 60 | } 61 | 62 | [Benchmark] 63 | [BenchmarkCategory(nameof(Grace))] 64 | public void Grace() 65 | { 66 | ExecuteBenchmark(GraceContainer); 67 | } 68 | 69 | [Benchmark] 70 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 71 | public void MicrosoftDependencyInjection() 72 | { 73 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 74 | } 75 | 76 | [Benchmark] 77 | [BenchmarkCategory(nameof(StructureMap))] 78 | public void StructureMap() 79 | { 80 | ExecuteBenchmark(StructureMapContainer); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Func/NoArgFuncBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Func 10 | { 11 | [BenchmarkCategory("Func")] 12 | public class NoArgFuncBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | "This benchmark registers a small objects then resolves a no argument function for each object"; 16 | 17 | protected override IEnumerable Definitions => SmallObjectServices.Definitions(); 18 | 19 | protected override void ExecuteBenchmark(IResolveScope scope) 20 | { 21 | scope.Resolve>()(); 22 | } 23 | 24 | [Benchmark] 25 | [BenchmarkCategory(nameof(Autofac))] 26 | public void Autofac() 27 | { 28 | ExecuteBenchmark(AutofacContainer); 29 | } 30 | 31 | [Benchmark] 32 | [BenchmarkCategory(nameof(DryIoc))] 33 | public void DryIoc() 34 | { 35 | ExecuteBenchmark(DryIocContainer); 36 | } 37 | 38 | [Benchmark] 39 | [BenchmarkCategory(nameof(Grace))] 40 | public void Grace() 41 | { 42 | ExecuteBenchmark(GraceContainer); 43 | } 44 | 45 | [Benchmark] 46 | [BenchmarkCategory(nameof(LightInject))] 47 | public void LightInject() 48 | { 49 | ExecuteBenchmark(LightInjectContainer); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Func/OneArgFuncBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Func 10 | { 11 | [BenchmarkCategory("Func")] 12 | public class OneArgFuncBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | "This benchmark registers a small object then resolves a one argument function for each object"; 16 | 17 | protected override IEnumerable Definitions 18 | { 19 | get 20 | { 21 | yield return new RegistrationDefinition { ExportType = typeof(ISmallObjectService), ActivationType = typeof(SmallObjectService) }; 22 | yield return new RegistrationDefinition { ExportType = typeof(ISingletonService), ActivationType = typeof(SingletonService), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 23 | } 24 | } 25 | 26 | protected override void ExecuteBenchmark(IResolveScope scope) 27 | { 28 | scope.Resolve>()(new TransientService()); 29 | } 30 | 31 | [Benchmark] 32 | [BenchmarkCategory(nameof(DryIoc))] 33 | public void DryIoc() 34 | { 35 | ExecuteBenchmark(DryIocContainer); 36 | } 37 | 38 | [Benchmark] 39 | [BenchmarkCategory(nameof(Grace))] 40 | public void Grace() 41 | { 42 | ExecuteBenchmark(GraceContainer); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Func/ThreeArgFuncBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Classes; 6 | using DotNet.DependencyInjectionBenchmarks.Containers; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Func 9 | { 10 | [BenchmarkCategory("Func")] 11 | public class ThreeArgFuncBenchmark : StandardBenchmark 12 | { 13 | public static string Description => 14 | "This benchmark registers a small object then resolves a three argument function for each object"; 15 | 16 | protected override IEnumerable Definitions 17 | { 18 | get 19 | { 20 | yield return new RegistrationDefinition 21 | { 22 | ExportType = typeof(IThreeArgService1), 23 | ActivationType = typeof(ThreeArgService1) 24 | }; 25 | } 26 | } 27 | 28 | protected override void ExecuteBenchmark(IResolveScope scope) 29 | { 30 | scope.Resolve>()(5, "Hello", 31 | new TransientService()); 32 | } 33 | 34 | [Benchmark] 35 | [BenchmarkCategory(nameof(DryIoc))] 36 | public void DryIoc() 37 | { 38 | ExecuteBenchmark(DryIocContainer); 39 | } 40 | 41 | [Benchmark] 42 | [BenchmarkCategory(nameof(Grace))] 43 | public void Grace() 44 | { 45 | ExecuteBenchmark(GraceContainer); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Lazy/LazyBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Lazy 10 | { 11 | [BenchmarkCategory("Lazy")] 12 | public class LazyBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | "This benchmark registers a small object then resolves the object using Lazy(T)."; 16 | 17 | protected override IEnumerable Definitions => SmallObjectServices.Definitions(); 18 | 19 | protected override void ExecuteBenchmark(IResolveScope scope) 20 | { 21 | if (scope.Resolve>().Value == null) 22 | { 23 | throw new Exception("Null lazy value"); 24 | } 25 | } 26 | 27 | [Benchmark] 28 | [BenchmarkCategory(nameof(Autofac))] 29 | public void Autofac() 30 | { 31 | ExecuteBenchmark(AutofacContainer); 32 | } 33 | 34 | [Benchmark] 35 | [BenchmarkCategory(nameof(CastleWindsor))] 36 | public void CastleWindsor() 37 | { 38 | ExecuteBenchmark(CastleWindsorContainer); 39 | } 40 | 41 | [Benchmark] 42 | [BenchmarkCategory(nameof(DryIoc))] 43 | public void DryIoc() 44 | { 45 | ExecuteBenchmark(DryIocContainer); 46 | } 47 | 48 | [Benchmark] 49 | [BenchmarkCategory(nameof(Grace))] 50 | public void Grace() 51 | { 52 | ExecuteBenchmark(GraceContainer); 53 | } 54 | 55 | [Benchmark] 56 | [BenchmarkCategory(nameof(LightInject))] 57 | public void LightInject() 58 | { 59 | ExecuteBenchmark(LightInjectContainer); 60 | } 61 | 62 | [Benchmark] 63 | [BenchmarkCategory(nameof(SimpleInjector))] 64 | public void SimpleInjector() 65 | { 66 | ExecuteBenchmark(LightInjectContainer); 67 | } 68 | 69 | [Benchmark] 70 | [BenchmarkCategory(nameof(StructureMap))] 71 | public void StructureMap() 72 | { 73 | ExecuteBenchmark(StructureMapContainer); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Lifestyles/SingletonPerAncestorBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Lifestyles 10 | { 11 | [BenchmarkCategory("Lifestyles")] 12 | public class SingletonPerAncestorBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | @"This benchmark registers a small object as Singleton Per Ancestor then resolves it as part of a slightly larger object graph"; 16 | 17 | protected override IEnumerable Definitions 18 | { 19 | get 20 | { 21 | foreach (var definition in SmallObjectServices.Definitions(RegistrationLifestyle.SingletonPerAncestor, typeof(IImportMultipleSmallObject))) 22 | { 23 | yield return definition; 24 | } 25 | 26 | yield return new RegistrationDefinition 27 | { 28 | ExportType = typeof(IImportMultipleSmallObject), 29 | ActivationType = typeof(ImportMultipleSmallObject) 30 | }; 31 | } 32 | } 33 | 34 | protected override void Warmup(IResolveScope scope) 35 | { 36 | var instance = scope.Resolve(); 37 | 38 | if (!ReferenceEquals(instance.SmallObject1, instance.SmallObject2)) 39 | { 40 | throw new Exception("Not the same instance"); 41 | } 42 | } 43 | 44 | protected override void ExecuteBenchmark(IResolveScope scope) 45 | { 46 | scope.Resolve(); 47 | } 48 | 49 | #region Benchmarks 50 | 51 | [Benchmark] 52 | [BenchmarkCategory(nameof(CastleWindsor))] 53 | public void CastleWindsor() 54 | { 55 | ExecuteBenchmark(CastleWindsorContainer); 56 | } 57 | 58 | [Benchmark] 59 | [BenchmarkCategory(nameof(Grace))] 60 | public void Grace() 61 | { 62 | ExecuteBenchmark(GraceContainer); 63 | } 64 | 65 | #endregion 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Lifestyles/SingletonPerObjectGraphBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Lifestyles 10 | { 11 | [BenchmarkCategory("Lifestyles")] 12 | public class SingletonPerObjectGraphBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | @"This benchmark registers a small object as Singleton Per Object Graph then resolves it as part of a slightly larger object graph"; 16 | 17 | protected override IEnumerable Definitions 18 | { 19 | get 20 | { 21 | foreach (var definition in SmallObjectServices.Definitions(RegistrationLifestyle.SingletonPerObjectGraph, typeof(IImportMultipleSmallObject))) 22 | { 23 | yield return definition; 24 | } 25 | 26 | yield return new RegistrationDefinition 27 | { 28 | ExportType = typeof(IImportMultipleSmallObject), 29 | ActivationType = typeof(ImportMultipleSmallObject) 30 | }; 31 | } 32 | } 33 | 34 | protected override void Warmup(IResolveScope scope) 35 | { 36 | var instance = scope.Resolve(); 37 | 38 | if (!ReferenceEquals(instance.SmallObject1, instance.SmallObject2)) 39 | { 40 | throw new Exception("Not the same instance"); 41 | } 42 | } 43 | 44 | protected override void ExecuteBenchmark(IResolveScope scope) 45 | { 46 | scope.Resolve(typeof(IImportMultipleSmallObject)); 47 | } 48 | 49 | [Benchmark] 50 | [BenchmarkCategory(nameof(CastleWindsor))] 51 | public void CastleWindsor() 52 | { 53 | ExecuteBenchmark(CastleWindsorContainer); 54 | } 55 | 56 | [Benchmark] 57 | [BenchmarkCategory(nameof(Grace))] 58 | public void Grace() 59 | { 60 | ExecuteBenchmark(GraceContainer); 61 | } 62 | 63 | [Benchmark] 64 | [BenchmarkCategory(nameof(StructureMap))] 65 | public void StructureMap() 66 | { 67 | ExecuteBenchmark(StructureMapContainer); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Lifestyles/SingletonPerScopeBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Lifestyles 10 | { 11 | [BenchmarkCategory("Lifestyles")] 12 | public class SingletonPerScopeBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | @"This benchmark registers a small object as Singleton Per Scope then creates a scope and resolves the small object."; 16 | 17 | protected override IEnumerable Definitions 18 | { 19 | get 20 | { 21 | foreach (var definition in SmallObjectServices.Definitions(RegistrationLifestyle.SingletonPerScope)) 22 | { 23 | yield return definition; 24 | } 25 | 26 | yield return new RegistrationDefinition 27 | { 28 | ExportType = typeof(IImportMultipleSmallObject), 29 | ActivationType = typeof(ImportMultipleSmallObject) 30 | }; 31 | } 32 | } 33 | 34 | protected override void Warmup(IResolveScope scope) 35 | { 36 | using (var childScope = scope.CreateScope()) 37 | { 38 | var instance = childScope.Resolve(); 39 | 40 | if (!ReferenceEquals(instance.SmallObject1, instance.SmallObject2)) 41 | { 42 | throw new Exception("Not the same instance"); 43 | } 44 | 45 | var instance2 = childScope.Resolve(); 46 | 47 | if (ReferenceEquals(instance, instance2)) 48 | { 49 | throw new Exception("Same instance"); 50 | } 51 | 52 | if (!ReferenceEquals(instance.SmallObject1, instance2.SmallObject1)) 53 | { 54 | throw new Exception("Small object1 not same instance"); 55 | } 56 | 57 | if (!ReferenceEquals(instance.SmallObject2, instance2.SmallObject2)) 58 | { 59 | throw new Exception("Small object2 not same instance"); 60 | } 61 | } 62 | } 63 | 64 | protected override void ExecuteBenchmark(IResolveScope scope) 65 | { 66 | using (var childScope = scope.CreateScope()) 67 | { 68 | childScope.Resolve(typeof(IImportMultipleSmallObject)); 69 | } 70 | } 71 | 72 | [Benchmark] 73 | [BenchmarkCategory(nameof(Autofac))] 74 | public void Autofac() 75 | { 76 | ExecuteBenchmark(AutofacContainer); 77 | } 78 | 79 | [Benchmark] 80 | [BenchmarkCategory(nameof(CastleWindsor))] 81 | public void CastleWindsor() 82 | { 83 | ExecuteBenchmark(CastleWindsorContainer); 84 | } 85 | 86 | [Benchmark] 87 | [BenchmarkCategory(nameof(DryIoc))] 88 | public void DryIoc() 89 | { 90 | ExecuteBenchmark(DryIocContainer); 91 | } 92 | 93 | [Benchmark] 94 | [BenchmarkCategory(nameof(Grace))] 95 | public void Grace() 96 | { 97 | ExecuteBenchmark(GraceContainer); 98 | } 99 | 100 | [Benchmark] 101 | [BenchmarkCategory(nameof(LightInject))] 102 | public void LightInject() 103 | { 104 | ExecuteBenchmark(LightInjectContainer); 105 | } 106 | 107 | [Benchmark] 108 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 109 | public void MicrosoftDependencyInjection() 110 | { 111 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 112 | } 113 | 114 | [Benchmark] 115 | [BenchmarkCategory(nameof(StructureMap))] 116 | public void StructureMap() 117 | { 118 | ExecuteBenchmark(StructureMapContainer); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Lookup/LookupBenchmark.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 3 | using DotNet.DependencyInjectionBenchmarks.Classes; 4 | using DotNet.DependencyInjectionBenchmarks.Containers; 5 | using System.Linq; 6 | 7 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Lookup 8 | { 9 | [BenchmarkCategory("Lookup")] 10 | public class LookupBenchmark : BaseBenchmark 11 | { 12 | public static string Description => 13 | @"This benchmark is designed to test the lookup performance of each container. One small object is resolved from the container along with {ExtraRegistrations} dummy registrations that are located at warmup time."; 14 | 15 | [Params(0, 50, 100, 500, 2000)] 16 | public int ExtraRegistrations { get; set; } 17 | 18 | [GlobalSetup(Target = nameof(Autofac))] 19 | public void AutofacSetup() 20 | { 21 | SetupContainerForLookup(CreateAutofacContainer()); 22 | } 23 | 24 | [Benchmark] 25 | [BenchmarkCategory(nameof(Autofac))] 26 | public void Autofac() 27 | { 28 | ExecuteBenchmark(AutofacContainer); 29 | } 30 | 31 | [GlobalSetup(Target = nameof(CastleWindsor))] 32 | public void CastleWindsorSetup() 33 | { 34 | SetupContainerForLookup(CreateCastleWindsorContainer()); 35 | } 36 | 37 | [Benchmark] 38 | [BenchmarkCategory(nameof(CastleWindsor))] 39 | public void CastleWindsor() 40 | { 41 | ExecuteBenchmark(CastleWindsorContainer); 42 | } 43 | 44 | [GlobalSetup(Target = nameof(DryIoc))] 45 | public void DryIocSetup() 46 | { 47 | SetupContainerForLookup(CreateDryIocContainer()); 48 | } 49 | 50 | [Benchmark] 51 | [BenchmarkCategory(nameof(DryIoc))] 52 | public void DryIoc() 53 | { 54 | ExecuteBenchmark(DryIocContainer); 55 | } 56 | 57 | [GlobalSetup(Target = nameof(Grace))] 58 | public void GraceSetup() 59 | { 60 | SetupContainerForLookup(CreateGraceContainer()); 61 | } 62 | 63 | [Benchmark] 64 | [BenchmarkCategory(nameof(Grace))] 65 | public void Grace() 66 | { 67 | ExecuteBenchmark(GraceContainer); 68 | } 69 | 70 | [GlobalSetup(Target = nameof(LightInject))] 71 | public void LightInjectSetup() 72 | { 73 | SetupContainerForLookup(CreateLightInjectContainer()); 74 | } 75 | 76 | [Benchmark] 77 | [BenchmarkCategory(nameof(LightInject))] 78 | public void LightInject() 79 | { 80 | ExecuteBenchmark(LightInjectContainer); 81 | } 82 | 83 | [GlobalSetup(Target = nameof(MicrosoftDependencyInjection))] 84 | public void MicrosoftDependencyInjectionSetup() 85 | { 86 | SetupContainerForLookup(CreateMicrosoftDependencyInjectionContainer()); 87 | } 88 | 89 | [Benchmark] 90 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 91 | public void MicrosoftDependencyInjection() 92 | { 93 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 94 | } 95 | 96 | [GlobalSetup(Target = nameof(NInject))] 97 | public void NInjectSetup() 98 | { 99 | SetupContainerForLookup(CreateLightInjectContainer()); 100 | } 101 | 102 | [Benchmark] 103 | [BenchmarkCategory(nameof(NInject))] 104 | public void NInject() 105 | { 106 | ExecuteBenchmark(NInjectContainer); 107 | } 108 | 109 | [GlobalSetup(Target = nameof(SimpleInjector))] 110 | public void SimpleInjectorSetup() 111 | { 112 | SetupContainerForLookup(CreateSimpleInjectorContainer()); 113 | } 114 | 115 | [Benchmark] 116 | [BenchmarkCategory(nameof(SimpleInjector))] 117 | public void SimpleInjector() 118 | { 119 | ExecuteBenchmark(SimpleInjectorContainer); 120 | } 121 | 122 | [GlobalSetup(Target = nameof(StructureMap))] 123 | public void StructureMapSetup() 124 | { 125 | SetupContainerForLookup(CreateStructureMapContainer()); 126 | } 127 | 128 | [Benchmark] 129 | [BenchmarkCategory(nameof(StructureMap))] 130 | public void StructureMap() 131 | { 132 | ExecuteBenchmark(StructureMapContainer); 133 | } 134 | 135 | public void SetupContainerForLookup(IContainer scope) 136 | { 137 | var allTypes = DummyClasses.GetTypes(ExtraRegistrations) 138 | .Select(t => new RegistrationDefinition { ExportType = t, ActivationType = t }).ToList(); 139 | 140 | var definitions = SmallObjectServices.Definitions().ToArray(); 141 | 142 | var gap = allTypes.Count / definitions.Length; 143 | 144 | var index = gap / 2; 145 | 146 | foreach (var definition in definitions) 147 | { 148 | allTypes.Insert(index, definition); 149 | 150 | index += gap + 1; 151 | } 152 | 153 | scope.Registration(allTypes); 154 | 155 | scope.BuildContainer(); 156 | 157 | foreach (var type in allTypes.Select(r => r.ExportType)) 158 | { 159 | scope.Resolve(type); 160 | } 161 | } 162 | 163 | private void ExecuteBenchmark(IResolveScope scope) 164 | { 165 | scope.Resolve(typeof(ISmallObjectService)); 166 | } 167 | 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/MemberInjection/PropertyInjectionBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using BenchmarkDotNet.Attributes; 5 | 6 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.MemberInjection 7 | { 8 | //public class PropertyInjectionBenchmark : BaseBenchmark 9 | //{ 10 | // [GlobalSetup] 11 | // public void Setup() 12 | // { 13 | 14 | // } 15 | //} 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Metadata/MetadataBenchmark.cs: -------------------------------------------------------------------------------- 1 | using AF = Autofac; 2 | using G = Grace; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using BenchmarkDotNet.Attributes; 6 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 7 | using DotNet.DependencyInjectionBenchmarks.Classes; 8 | using DotNet.DependencyInjectionBenchmarks.Containers; 9 | 10 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Metadata 11 | { 12 | [BenchmarkCategory("Metadata")] 13 | public class MetadataBenchmark : BaseBenchmark 14 | { 15 | public static string Description => 16 | "This benchmark registers types with metadata then resolves a untyped metadata model along side the desired service."; 17 | 18 | [GlobalSetup] 19 | public void Setup() 20 | { 21 | var definitions = Definitions().ToArray(); 22 | 23 | SetupContainerForTest(CreateAutofacContainer(), definitions); 24 | SetupContainerForTest(CreateGraceContainer(), definitions); 25 | } 26 | 27 | public static IEnumerable Definitions() 28 | { 29 | var metadata = new Dictionary 30 | { 31 | { "IntProp", 5}, 32 | { "DoubleProp", 5.0 }, 33 | { "StringProp", "StringValue1" } 34 | }; 35 | 36 | yield return new RegistrationDefinition { ExportType = typeof(ISmallObjectService), ActivationType = typeof(SmallObjectService), Metadata = metadata }; 37 | yield return new RegistrationDefinition { ExportType = typeof(ITransientService), ActivationType = typeof(TransientService) }; 38 | yield return new RegistrationDefinition { ExportType = typeof(ISingletonService), ActivationType = typeof(SingletonService), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 39 | 40 | } 41 | 42 | #region Benchmarks 43 | 44 | [Benchmark] 45 | [BenchmarkCategory(nameof(Autofac))] 46 | public void Autofac() 47 | { 48 | AutofacContainer.Resolve>(); 49 | } 50 | 51 | [Benchmark] 52 | [BenchmarkCategory(nameof(Grace))] 53 | public void Grace() 54 | { 55 | GraceContainer.Resolve>(); 56 | } 57 | 58 | #endregion 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Metadata/StronglyTypedMetadataBenchmark.cs: -------------------------------------------------------------------------------- 1 | using AF = Autofac; 2 | using G = Grace; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using BenchmarkDotNet.Attributes; 6 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 7 | using DotNet.DependencyInjectionBenchmarks.Classes; 8 | using DotNet.DependencyInjectionBenchmarks.Containers; 9 | 10 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Metadata 11 | { 12 | [BenchmarkCategory("Metadata")] 13 | public class StronglyTypedMetadataBenchmark : BaseBenchmark 14 | { 15 | public static string Description => 16 | "This benchmark registers types with metadata then resolves a strongly type metadata model along side the desired service."; 17 | 18 | [GlobalSetup] 19 | public void Setup() 20 | { 21 | var definitions = Definitions().ToArray(); 22 | 23 | SetupContainerForTest(CreateAutofacContainer(), definitions); 24 | SetupContainerForTest(CreateGraceContainer(), definitions); 25 | } 26 | 27 | public static IEnumerable Definitions() 28 | { 29 | var metadata = new Dictionary 30 | { 31 | { "IntProp", 5}, 32 | { "DoubleProp", 5.0 }, 33 | { "StringProp", "StringValue1" } 34 | }; 35 | 36 | yield return new RegistrationDefinition { ExportType = typeof(ISmallObjectService), ActivationType = typeof(SmallObjectService), Metadata = metadata }; 37 | yield return new RegistrationDefinition { ExportType = typeof(ITransientService), ActivationType = typeof(TransientService) }; 38 | yield return new RegistrationDefinition { ExportType = typeof(ISingletonService), ActivationType = typeof(SingletonService), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 39 | 40 | } 41 | 42 | #region Benchmarks 43 | 44 | [Benchmark] 45 | [BenchmarkCategory(nameof(Autofac))] 46 | public void Autofac() 47 | { 48 | AutofacContainer.Resolve>(); 49 | } 50 | 51 | [Benchmark] 52 | [BenchmarkCategory(nameof(Autofac))] 53 | public void Grace() 54 | { 55 | GraceContainer.Resolve>(); 56 | } 57 | 58 | #endregion 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Registration/RegistrationBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Autofac; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Classes; 6 | using DryIoc; 7 | using Grace.DependencyInjection; 8 | using Grace.Dynamic; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Ninject; 11 | 12 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Registration 13 | { 14 | public enum ResolveScenario 15 | { 16 | ResolveNone, 17 | ResolveOne, 18 | ResolveHalf, 19 | ResolveAll 20 | } 21 | 22 | [BenchmarkCategory("Registration")] 23 | public class RegistrationBenchmark 24 | { 25 | private Type[] _types; 26 | 27 | [Params(10, 100, 500)] 28 | public int Registrations { get; set; } 29 | 30 | [Params(ResolveScenario.ResolveNone, ResolveScenario.ResolveOne, ResolveScenario.ResolveHalf, ResolveScenario.ResolveAll)] 31 | public ResolveScenario Scenario { get; set; } 32 | 33 | public static string Description => 34 | "This benchmark registers {Registrations} classes then {Scenario} from the container"; 35 | 36 | [GlobalSetup] 37 | public void Setup() 38 | { 39 | _types = DummyClasses.GetTypes(Registrations).ToArray(); 40 | } 41 | 42 | [Benchmark] 43 | [BenchmarkCategory(nameof(Autofac))] 44 | public void Autofac() 45 | { 46 | var containerBuilder = new ContainerBuilder(); 47 | 48 | foreach (var type in _types) 49 | { 50 | containerBuilder.RegisterType(type).As(type); 51 | } 52 | 53 | var container = containerBuilder.Build(); 54 | int length = 0; 55 | 56 | if (Scenario == ResolveScenario.ResolveOne) 57 | { 58 | length = 1; 59 | } 60 | else if (Scenario == ResolveScenario.ResolveHalf) 61 | { 62 | length = _types.Length / 2; 63 | } 64 | else if (Scenario == ResolveScenario.ResolveAll) 65 | { 66 | length = _types.Length; 67 | } 68 | 69 | for (var i = 0; i < length; i++) 70 | { 71 | container.Resolve(_types[i]); 72 | } 73 | 74 | container.Dispose(); 75 | } 76 | 77 | [Benchmark] 78 | [BenchmarkCategory(nameof(DryIoc))] 79 | public void DryIoc() 80 | { 81 | var container = new DryIoc.Container(); 82 | 83 | foreach (var type in _types) 84 | { 85 | container.Register(type, type); 86 | } 87 | int length = 0; 88 | 89 | if (Scenario == ResolveScenario.ResolveOne) 90 | { 91 | length = 1; 92 | } 93 | else if (Scenario == ResolveScenario.ResolveHalf) 94 | { 95 | length = _types.Length / 2; 96 | } 97 | else if (Scenario == ResolveScenario.ResolveAll) 98 | { 99 | length = _types.Length; 100 | } 101 | 102 | for (var i = 0; i < length; i++) 103 | { 104 | container.Resolve(_types[i]); 105 | } 106 | 107 | container.Dispose(); 108 | } 109 | 110 | [Benchmark] 111 | [BenchmarkCategory(nameof(Grace))] 112 | public void Grace() 113 | { 114 | var container = new DependencyInjectionContainer(GraceDynamicMethod.Configuration()); 115 | 116 | container.Configure(c => 117 | { 118 | foreach (var type in _types) 119 | { 120 | c.Export(type).As(type); 121 | } 122 | }); 123 | 124 | int length = 0; 125 | 126 | if (Scenario == ResolveScenario.ResolveOne) 127 | { 128 | length = 1; 129 | } 130 | else if (Scenario == ResolveScenario.ResolveHalf) 131 | { 132 | length = _types.Length / 2; 133 | } 134 | else if (Scenario == ResolveScenario.ResolveAll) 135 | { 136 | length = _types.Length; 137 | } 138 | 139 | for (var i = 0; i < length; i++) 140 | { 141 | container.Locate(_types[i]); 142 | } 143 | 144 | container.Dispose(); 145 | } 146 | 147 | [Benchmark] 148 | [BenchmarkCategory(nameof(LightInject))] 149 | public void LightInject() 150 | { 151 | var container = new LightInject.ServiceContainer(); 152 | 153 | foreach (var type in _types) 154 | { 155 | container.Register(type, type); 156 | } 157 | 158 | int length = 0; 159 | 160 | if (Scenario == ResolveScenario.ResolveOne) 161 | { 162 | length = 1; 163 | } 164 | else if (Scenario == ResolveScenario.ResolveHalf) 165 | { 166 | length = _types.Length / 2; 167 | } 168 | else if (Scenario == ResolveScenario.ResolveAll) 169 | { 170 | length = _types.Length; 171 | } 172 | 173 | for (var i = 0; i < length; i++) 174 | { 175 | container.GetInstance(_types[i]); 176 | } 177 | 178 | container.Dispose(); 179 | } 180 | 181 | [Benchmark] 182 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 183 | public void MicrosoftDependencyInjection() 184 | { 185 | var serviceCollection = new ServiceCollection(); 186 | 187 | foreach (var type in _types) 188 | { 189 | serviceCollection.AddTransient(type, type); 190 | } 191 | 192 | var container = serviceCollection.BuildServiceProvider(); 193 | 194 | int length = 0; 195 | 196 | if (Scenario == ResolveScenario.ResolveOne) 197 | { 198 | length = 1; 199 | } 200 | else if (Scenario == ResolveScenario.ResolveHalf) 201 | { 202 | length = _types.Length / 2; 203 | } 204 | else if (Scenario == ResolveScenario.ResolveAll) 205 | { 206 | length = _types.Length; 207 | } 208 | 209 | for (var i = 0; i < length; i++) 210 | { 211 | container.GetService(_types[i]); 212 | } 213 | 214 | ((IDisposable)container).Dispose(); 215 | } 216 | 217 | [Benchmark] 218 | [BenchmarkCategory(nameof(NInject))] 219 | public void NInject() 220 | { 221 | var configuration = new KernelConfiguration(); 222 | 223 | foreach (var type in _types) 224 | { 225 | configuration.Bind(type).To(type); 226 | } 227 | 228 | var container = configuration.BuildReadonlyKernel(); 229 | 230 | int length = 0; 231 | 232 | if (Scenario == ResolveScenario.ResolveOne) 233 | { 234 | length = 1; 235 | } 236 | else if (Scenario == ResolveScenario.ResolveHalf) 237 | { 238 | length = _types.Length / 2; 239 | } 240 | else if (Scenario == ResolveScenario.ResolveAll) 241 | { 242 | length = _types.Length; 243 | } 244 | 245 | for (var i = 0; i < length; i++) 246 | { 247 | container.GetService(_types[i]); 248 | } 249 | 250 | container.Dispose(); 251 | } 252 | 253 | [Benchmark] 254 | [BenchmarkCategory(nameof(SimpleInjector))] 255 | public void SimpleInjector() 256 | { 257 | var container = new SimpleInjector.Container(); 258 | 259 | foreach (var type in _types) 260 | { 261 | container.Register(type, type); 262 | } 263 | 264 | int length = 0; 265 | 266 | if (Scenario == ResolveScenario.ResolveOne) 267 | { 268 | length = 1; 269 | } 270 | else if (Scenario == ResolveScenario.ResolveHalf) 271 | { 272 | length = _types.Length / 2; 273 | } 274 | else if (Scenario == ResolveScenario.ResolveAll) 275 | { 276 | length = _types.Length; 277 | } 278 | 279 | for (var i = 0; i < length; i++) 280 | { 281 | container.GetInstance(_types[i]); 282 | } 283 | 284 | container.Dispose(); 285 | } 286 | 287 | [Benchmark] 288 | [BenchmarkCategory(nameof(StructureMap))] 289 | public void StructureMap() 290 | { 291 | var container = new StructureMap.Container(); 292 | 293 | foreach (var type in _types) 294 | { 295 | container.Configure(c => c.For(type).Use(type)); 296 | } 297 | 298 | int length = 0; 299 | 300 | if (Scenario == ResolveScenario.ResolveOne) 301 | { 302 | length = 1; 303 | } 304 | else if (Scenario == ResolveScenario.ResolveHalf) 305 | { 306 | length = _types.Length / 2; 307 | } 308 | else if (Scenario == ResolveScenario.ResolveAll) 309 | { 310 | length = _types.Length; 311 | } 312 | 313 | for (var i = 0; i < length; i++) 314 | { 315 | container.GetInstance(_types[i]); 316 | } 317 | 318 | container.Dispose(); 319 | } 320 | } 321 | } 322 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Scoped/CreateScopeAndResolveBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using BenchmarkDotNet.Attributes; 4 | using DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard; 5 | using DotNet.DependencyInjectionBenchmarks.Classes; 6 | using DotNet.DependencyInjectionBenchmarks.Containers; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Scoped 9 | { 10 | [BenchmarkCategory("Scoped")] 11 | public class CreateScopeAndResolveBenchmark : StandardBenchmark 12 | { 13 | public static string Description => 14 | "This benchmark creates a lifetime scope and then resolves a small object from the child scope."; 15 | 16 | protected override IEnumerable Definitions => SmallObjectServices.Definitions(); 17 | 18 | protected override void ExecuteBenchmark(IResolveScope scope) 19 | { 20 | using (var childScope = scope.CreateScope()) 21 | { 22 | childScope.Resolve(typeof(ISmallObjectService)); 23 | } 24 | } 25 | 26 | [Benchmark] 27 | [BenchmarkCategory(nameof(Autofac))] 28 | public void Autofac() 29 | { 30 | ExecuteBenchmark(AutofacContainer); 31 | } 32 | 33 | [Benchmark] 34 | [BenchmarkCategory(nameof(CastleWindsor))] 35 | public void CastleWindsor() 36 | { 37 | ExecuteBenchmark(CastleWindsorContainer); 38 | } 39 | 40 | [Benchmark] 41 | [BenchmarkCategory(nameof(DryIoc))] 42 | public void DryIoc() 43 | { 44 | ExecuteBenchmark(DryIocContainer); 45 | } 46 | 47 | [Benchmark] 48 | [BenchmarkCategory(nameof(Grace))] 49 | public void Grace() 50 | { 51 | ExecuteBenchmark(GraceContainer); 52 | } 53 | 54 | [Benchmark] 55 | [BenchmarkCategory(nameof(LightInject))] 56 | public void LightInject() 57 | { 58 | ExecuteBenchmark(LightInjectContainer); 59 | } 60 | 61 | [Benchmark] 62 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 63 | public void MicrosoftDependencyInjection() 64 | { 65 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 66 | } 67 | 68 | [Benchmark] 69 | [BenchmarkCategory(nameof(StructureMap))] 70 | public void StructureMap() 71 | { 72 | ExecuteBenchmark(StructureMapContainer); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Standard/EnumerableBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Classes; 6 | using DotNet.DependencyInjectionBenchmarks.Containers; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard 9 | { 10 | [BenchmarkCategory("Standard")] 11 | public class EnumerableBenchmark : StandardBenchmark 12 | { 13 | public static string Description => 14 | @"Resolves one object that depends on an enumerable containing 5 instances"; 15 | 16 | protected override IEnumerable Definitions 17 | { 18 | get 19 | { 20 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService1), RegistrationMode = RegistrationMode.Multiple }; 21 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService2), RegistrationMode = RegistrationMode.Multiple }; 22 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService3), RegistrationMode = RegistrationMode.Multiple }; 23 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService4), RegistrationMode = RegistrationMode.Multiple }; 24 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService5), RegistrationMode = RegistrationMode.Multiple }; 25 | yield return new RegistrationDefinition { ExportType = typeof(ISingletonService), ActivationType = typeof(SingletonService) }; 26 | yield return new RegistrationDefinition { ExportType = typeof(ITransientService), ActivationType = typeof(TransientService) }; 27 | 28 | yield return new RegistrationDefinition { ExportType = typeof(IImportEnumerableService), ActivationType = typeof(ImportEnumerableService) }; 29 | } 30 | } 31 | 32 | protected override void ExecuteBenchmark(IResolveScope scope) 33 | { 34 | if (scope.Resolve().Services.Count() != 5) 35 | { 36 | throw new Exception("Count does not equal 5"); 37 | } 38 | } 39 | 40 | [Benchmark] 41 | [BenchmarkCategory(nameof(Autofac))] 42 | public void Autofac() 43 | { 44 | ExecuteBenchmark(AutofacContainer); 45 | } 46 | 47 | [Benchmark] 48 | [BenchmarkCategory(nameof(CastleWindsor))] 49 | public void CastleWindsor() 50 | { 51 | ExecuteBenchmark(CastleWindsorContainer); 52 | } 53 | 54 | [Benchmark] 55 | [BenchmarkCategory(nameof(DryIoc))] 56 | public void DryIoc() 57 | { 58 | ExecuteBenchmark(DryIocContainer); 59 | } 60 | 61 | [Benchmark] 62 | [BenchmarkCategory(nameof(Grace))] 63 | public void Grace() 64 | { 65 | ExecuteBenchmark(GraceContainer); 66 | } 67 | 68 | [Benchmark] 69 | [BenchmarkCategory(nameof(LightInject))] 70 | public void LightInject() 71 | { 72 | ExecuteBenchmark(LightInjectContainer); 73 | } 74 | 75 | [Benchmark] 76 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 77 | public void MicrosoftDependencyInjection() 78 | { 79 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 80 | } 81 | 82 | [Benchmark] 83 | [BenchmarkCategory(nameof(NInject))] 84 | public void NInject() 85 | { 86 | ExecuteBenchmark(NInjectContainer); 87 | } 88 | 89 | [Benchmark] 90 | [BenchmarkCategory(nameof(SimpleInjector))] 91 | public void SimpleInjector() 92 | { 93 | ExecuteBenchmark(SimpleInjectorContainer); 94 | } 95 | 96 | [Benchmark] 97 | [BenchmarkCategory(nameof(StructureMap))] 98 | public void StructureMap() 99 | { 100 | ExecuteBenchmark(StructureMapContainer); 101 | } 102 | 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Standard/GenericObjectBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using BenchmarkDotNet.Attributes; 6 | using DotNet.DependencyInjectionBenchmarks.Classes; 7 | using DotNet.DependencyInjectionBenchmarks.Containers; 8 | 9 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard 10 | { 11 | [BenchmarkCategory("Standard")] 12 | public class GenericObjectBenchmark : StandardBenchmark 13 | { 14 | public static string Description => 15 | @"Registers a small object graph as well as one generic service and resolves it."; 16 | 17 | protected override IEnumerable Definitions 18 | { 19 | get 20 | { 21 | foreach (var registrationDefinition in SmallObjectServices.Definitions()) 22 | { 23 | yield return registrationDefinition; 24 | } 25 | 26 | yield return new RegistrationDefinition { ExportType = typeof(IGenericObjectService<>), ActivationType = typeof(GenericObjectService<>) }; 27 | } 28 | } 29 | 30 | protected override void ExecuteBenchmark(IResolveScope scope) 31 | { 32 | scope.Resolve(typeof(IGenericObjectService)); 33 | } 34 | 35 | [Benchmark] 36 | [BenchmarkCategory(nameof(Autofac))] 37 | public void Autofac() 38 | { 39 | ExecuteBenchmark(AutofacContainer); 40 | } 41 | 42 | [Benchmark] 43 | [BenchmarkCategory(nameof(CastleWindsor))] 44 | public void CastleWindsor() 45 | { 46 | ExecuteBenchmark(CastleWindsorContainer); 47 | } 48 | 49 | [Benchmark] 50 | [BenchmarkCategory(nameof(DryIoc))] 51 | public void DryIoc() 52 | { 53 | ExecuteBenchmark(DryIocContainer); 54 | } 55 | 56 | [Benchmark] 57 | [BenchmarkCategory(nameof(Grace))] 58 | public void Grace() 59 | { 60 | ExecuteBenchmark(GraceContainer); 61 | } 62 | 63 | [Benchmark] 64 | [BenchmarkCategory(nameof(LightInject))] 65 | public void LightInject() 66 | { 67 | ExecuteBenchmark(LightInjectContainer); 68 | } 69 | 70 | [Benchmark] 71 | [BenchmarkCategory(nameof(NInject))] 72 | public void NInject() 73 | { 74 | ExecuteBenchmark(NInjectContainer); 75 | } 76 | 77 | [Benchmark] 78 | [BenchmarkCategory(nameof(SimpleInjector))] 79 | public void SimpleInjector() 80 | { 81 | ExecuteBenchmark(SimpleInjectorContainer); 82 | } 83 | 84 | [Benchmark] 85 | [BenchmarkCategory(nameof(StructureMap))] 86 | public void StructureMap() 87 | { 88 | ExecuteBenchmark(StructureMapContainer); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Standard/LargeObjectBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using BenchmarkDotNet.Attributes; 4 | using DotNet.DependencyInjectionBenchmarks.Classes; 5 | using DotNet.DependencyInjectionBenchmarks.Containers; 6 | 7 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard 8 | { 9 | [BenchmarkCategory("Standard")] 10 | public class LargeObjectBenchmark : StandardBenchmark 11 | { 12 | public static string Description => 13 | @"Resolves a Large object graph containing 7 transients and 3 Singletons from each container"; 14 | 15 | protected override IEnumerable Definitions 16 | { 17 | get 18 | { 19 | yield return new RegistrationDefinition { ExportType = typeof(ILargeSingletonService1), ActivationType = typeof(LargeSingletonService1), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 20 | yield return new RegistrationDefinition { ExportType = typeof(ILargeSingletonService2), ActivationType = typeof(LargeSingletonService2), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 21 | yield return new RegistrationDefinition { ExportType = typeof(ILargeSingletonService3), ActivationType = typeof(LargeSingletonService3), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 22 | 23 | yield return new RegistrationDefinition { ExportType = typeof(ILargeComplexService), ActivationType = typeof(LargeComplexService) }; 24 | 25 | yield return new RegistrationDefinition { ExportType = typeof(ILargeTransient1), ActivationType = typeof(LargeTransient1) }; 26 | yield return new RegistrationDefinition { ExportType = typeof(ILargeTransient2), ActivationType = typeof(LargeTransient2) }; 27 | yield return new RegistrationDefinition { ExportType = typeof(ILargeTransient3), ActivationType = typeof(LargeTransient3) }; 28 | 29 | yield return new RegistrationDefinition { ExportType = typeof(ILargeObjectService1), ActivationType = typeof(LargeObjectService1) }; 30 | yield return new RegistrationDefinition { ExportType = typeof(ILargeObjectService2), ActivationType = typeof(LargeObjectService2) }; 31 | yield return new RegistrationDefinition { ExportType = typeof(ILargeObjectService3), ActivationType = typeof(LargeObjectService3) }; 32 | } 33 | } 34 | 35 | protected override void ExecuteBenchmark(IResolveScope scope) 36 | { 37 | scope.Resolve(typeof(ILargeComplexService)); 38 | } 39 | 40 | #region Benchmarks 41 | 42 | [Benchmark] 43 | [BenchmarkCategory(nameof(Autofac))] 44 | public void Autofac() 45 | { 46 | ExecuteBenchmark(AutofacContainer); 47 | } 48 | 49 | [Benchmark] 50 | [BenchmarkCategory(nameof(CastleWindsor))] 51 | public void CastleWindsor() 52 | { 53 | ExecuteBenchmark(CastleWindsorContainer); 54 | } 55 | 56 | [Benchmark] 57 | [BenchmarkCategory(nameof(DryIoc))] 58 | public void DryIoc() 59 | { 60 | ExecuteBenchmark(DryIocContainer); 61 | } 62 | 63 | [Benchmark] 64 | [BenchmarkCategory(nameof(Grace))] 65 | public void Grace() 66 | { 67 | ExecuteBenchmark(GraceContainer); 68 | } 69 | 70 | [Benchmark] 71 | [BenchmarkCategory(nameof(LightInject))] 72 | public void LightInject() 73 | { 74 | ExecuteBenchmark(LightInjectContainer); 75 | } 76 | 77 | [Benchmark] 78 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 79 | public void MicrosoftDependencyInjection() 80 | { 81 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 82 | } 83 | 84 | [Benchmark] 85 | [BenchmarkCategory(nameof(NInject))] 86 | public void NInject() 87 | { 88 | ExecuteBenchmark(NInjectContainer); 89 | } 90 | 91 | [Benchmark] 92 | [BenchmarkCategory(nameof(SimpleInjector))] 93 | public void SimpleInjector() 94 | { 95 | ExecuteBenchmark(SimpleInjectorContainer); 96 | } 97 | 98 | [Benchmark] 99 | [BenchmarkCategory(nameof(StructureMap))] 100 | public void StructureMap() 101 | { 102 | ExecuteBenchmark(StructureMapContainer); 103 | } 104 | 105 | #endregion 106 | 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Standard/SingletonBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using BenchmarkDotNet.Attributes; 4 | using DotNet.DependencyInjectionBenchmarks.Classes; 5 | using DotNet.DependencyInjectionBenchmarks.Containers; 6 | 7 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard 8 | { 9 | [BenchmarkCategory("Standard")] 10 | public class SingletonBenchmark : StandardBenchmark 11 | { 12 | public static string Description => 13 | @"Resolves a Singleton services from each container"; 14 | 15 | protected override IEnumerable Definitions 16 | { 17 | get 18 | { 19 | yield return new RegistrationDefinition { ExportType = typeof(ISingletonService), ActivationType = typeof(SingletonService), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 20 | } 21 | } 22 | 23 | protected override void ExecuteBenchmark(IResolveScope scope) 24 | { 25 | scope.Resolve(typeof(ISingletonService)); 26 | } 27 | 28 | [Benchmark] 29 | [BenchmarkCategory(nameof(Autofac))] 30 | public void Autofac() 31 | { 32 | ExecuteBenchmark(AutofacContainer); 33 | } 34 | 35 | [Benchmark] 36 | [BenchmarkCategory(nameof(CastleWindsor))] 37 | public void CastleWindsor() 38 | { 39 | ExecuteBenchmark(CastleWindsorContainer); 40 | } 41 | 42 | [Benchmark] 43 | [BenchmarkCategory(nameof(DryIoc))] 44 | public void DryIoc() 45 | { 46 | ExecuteBenchmark(DryIocContainer); 47 | } 48 | 49 | [Benchmark] 50 | [BenchmarkCategory(nameof(Grace))] 51 | public void Grace() 52 | { 53 | ExecuteBenchmark(GraceContainer); 54 | } 55 | 56 | [Benchmark] 57 | [BenchmarkCategory(nameof(LightInject))] 58 | public void LightInject() 59 | { 60 | ExecuteBenchmark(LightInjectContainer); 61 | } 62 | 63 | [Benchmark] 64 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 65 | public void MicrosoftDependencyInjection() 66 | { 67 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 68 | } 69 | 70 | [Benchmark] 71 | [BenchmarkCategory(nameof(NInject))] 72 | public void NInject() 73 | { 74 | ExecuteBenchmark(NInjectContainer); 75 | } 76 | 77 | [Benchmark] 78 | [BenchmarkCategory(nameof(SimpleInjector))] 79 | public void SimpleInjector() 80 | { 81 | ExecuteBenchmark(SimpleInjectorContainer); 82 | } 83 | 84 | [Benchmark] 85 | [BenchmarkCategory(nameof(StructureMap))] 86 | public void StructureMap() 87 | { 88 | ExecuteBenchmark(StructureMapContainer); 89 | } 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/Standard/SmallObjectBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Classes; 6 | using DotNet.DependencyInjectionBenchmarks.Containers; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks.Standard 9 | { 10 | [BenchmarkCategory("Standard")] 11 | public class SmallObjectBenchmark : StandardBenchmark 12 | { 13 | public static string Description => 14 | @"Resolves a small object graph containing two transients and a Singleton from each container"; 15 | 16 | protected override IEnumerable Definitions => SmallObjectServices.Definitions(); 17 | 18 | protected override void ExecuteBenchmark(IResolveScope scope) 19 | { 20 | scope.Resolve(typeof(ISmallObjectService)); 21 | } 22 | 23 | [Benchmark] 24 | [BenchmarkCategory(nameof(Autofac))] 25 | public void Autofac() 26 | { 27 | ExecuteBenchmark(AutofacContainer); 28 | } 29 | 30 | [Benchmark] 31 | [BenchmarkCategory(nameof(CastleWindsor))] 32 | public void CastleWindsor() 33 | { 34 | ExecuteBenchmark(CastleWindsorContainer); 35 | } 36 | 37 | [Benchmark] 38 | [BenchmarkCategory(nameof(DryIoc))] 39 | public void DryIoc() 40 | { 41 | ExecuteBenchmark(DryIocContainer); 42 | } 43 | 44 | [Benchmark] 45 | [BenchmarkCategory(nameof(Grace))] 46 | public void Grace() 47 | { 48 | ExecuteBenchmark(GraceContainer); 49 | } 50 | 51 | [Benchmark] 52 | [BenchmarkCategory(nameof(LightInject))] 53 | public void LightInject() 54 | { 55 | ExecuteBenchmark(LightInjectContainer); 56 | } 57 | 58 | [Benchmark] 59 | [BenchmarkCategory(nameof(MicrosoftDependencyInjection))] 60 | public void MicrosoftDependencyInjection() 61 | { 62 | ExecuteBenchmark(MicrosoftDependencyInjectionContainer); 63 | } 64 | 65 | [Benchmark] 66 | [BenchmarkCategory(nameof(NInject))] 67 | public void NInject() 68 | { 69 | ExecuteBenchmark(NInjectContainer); 70 | } 71 | 72 | [Benchmark] 73 | [BenchmarkCategory(nameof(SimpleInjector))] 74 | public void SimpleInjector() 75 | { 76 | ExecuteBenchmark(SimpleInjectorContainer); 77 | } 78 | 79 | [Benchmark] 80 | [BenchmarkCategory(nameof(StructureMap))] 81 | public void StructureMap() 82 | { 83 | ExecuteBenchmark(StructureMapContainer); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Benchmarks/StandardBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using BenchmarkDotNet.Attributes; 5 | using DotNet.DependencyInjectionBenchmarks.Containers; 6 | 7 | namespace DotNet.DependencyInjectionBenchmarks.Benchmarks 8 | { 9 | public abstract class StandardBenchmark : BaseBenchmark 10 | { 11 | [GlobalSetup(Target = "Autofac")] 12 | public void AutofacSetup() 13 | { 14 | SetupContainerForTest(CreateAutofacContainer(), Definitions, Warmup); 15 | } 16 | 17 | [GlobalSetup(Target = "CastleWindsor")] 18 | public void CastleWindsorSetup() 19 | { 20 | SetupContainerForTest(CreateCastleWindsorContainer(), Definitions, Warmup); 21 | } 22 | 23 | [GlobalSetup(Target = "DryIoc")] 24 | public void DryIocSetup() 25 | { 26 | SetupContainerForTest(CreateDryIocContainer(), Definitions, Warmup); 27 | } 28 | 29 | [GlobalSetup(Target = "Grace")] 30 | public void GraceSetup() 31 | { 32 | SetupContainerForTest(CreateGraceContainer(), Definitions, Warmup); 33 | } 34 | 35 | [GlobalSetup(Target = "LightInject")] 36 | public void LightInjectSetup() 37 | { 38 | SetupContainerForTest(CreateLightInjectContainer(), Definitions, Warmup); 39 | } 40 | 41 | [GlobalSetup(Target = "MicrosoftDependencyInjection")] 42 | public void MicrosoftDependencyInjectionSetup() 43 | { 44 | SetupContainerForTest(CreateMicrosoftDependencyInjectionContainer(), Definitions, Warmup); 45 | } 46 | 47 | [GlobalSetup(Target = "NInject")] 48 | public void NInjectSetup() 49 | { 50 | SetupContainerForTest(CreateLightInjectContainer(), Definitions, Warmup); 51 | } 52 | 53 | [GlobalSetup(Target = "SimpleInjector")] 54 | public void SimpleInjectorSetup() 55 | { 56 | SetupContainerForTest(CreateSimpleInjectorContainer(), Definitions, Warmup); 57 | } 58 | 59 | [GlobalSetup(Target = "StructureMap")] 60 | public void StructureMapSetup() 61 | { 62 | SetupContainerForTest(CreateStructureMapContainer(), Definitions, Warmup); 63 | } 64 | 65 | protected virtual void Warmup(IResolveScope scope) 66 | { 67 | ExecuteBenchmark(scope); 68 | } 69 | 70 | protected abstract IEnumerable Definitions { get; } 71 | 72 | protected abstract void ExecuteBenchmark(IResolveScope scope); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/DummyClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Reflection.Emit; 5 | 6 | namespace DotNet.DependencyInjectionBenchmarks.Classes 7 | { 8 | public static class DummyClasses 9 | { 10 | private static readonly object _lock = new object(); 11 | private static readonly List _types = new List(); 12 | private static readonly ModuleBuilder _moduleBuilder; 13 | 14 | static DummyClasses() 15 | { 16 | var dynamicAssembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run); 17 | 18 | _moduleBuilder = dynamicAssembly.DefineDynamicModule("DummyTypes"); 19 | } 20 | 21 | public static IEnumerable GetTypes(int count) 22 | { 23 | if (count <= (_types.Count - 1)) 24 | { 25 | return _types.GetRange(0, count); 26 | } 27 | 28 | GenerateTypes(_types.Count, count - _types.Count); 29 | 30 | return _types; 31 | } 32 | 33 | private static void GenerateTypes(int index, int count) 34 | { 35 | lock (_lock) 36 | { 37 | for (var i = index; i < index + count; i++) 38 | { 39 | var proxyBuilder = _moduleBuilder.DefineType("DummyType" + i, 40 | TypeAttributes.Class | TypeAttributes.Public); 41 | 42 | _types.Add(proxyBuilder.CreateTypeInfo().AsType()); 43 | } 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/EnumerableServices.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using DotNet.DependencyInjectionBenchmarks.Containers; 3 | 4 | namespace DotNet.DependencyInjectionBenchmarks.Classes 5 | { 6 | public static class EnumerableServices 7 | { 8 | public static IEnumerable Definitions() 9 | { 10 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService1), RegistrationMode = RegistrationMode.Multiple }; 11 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService2), RegistrationMode = RegistrationMode.Multiple }; 12 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService3), RegistrationMode = RegistrationMode.Multiple }; 13 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService4), RegistrationMode = RegistrationMode.Multiple }; 14 | yield return new RegistrationDefinition { ExportType = typeof(IEnumerableService), ActivationType = typeof(EnumerableService5), RegistrationMode = RegistrationMode.Multiple }; 15 | yield return new RegistrationDefinition { ExportType = typeof(ISingletonService), ActivationType = typeof(SingletonService) }; 16 | yield return new RegistrationDefinition { ExportType = typeof(ITransientService), ActivationType = typeof(TransientService) }; 17 | } 18 | } 19 | 20 | public interface IEnumerableService 21 | { 22 | ISingletonService Singleton { get; } 23 | 24 | ITransientService Transient { get; } 25 | } 26 | 27 | public class EnumerableService1 : IEnumerableService 28 | { 29 | public EnumerableService1(ITransientService transient, ISingletonService singleton) 30 | { 31 | Transient = transient; 32 | Singleton = singleton; 33 | } 34 | 35 | public ISingletonService Singleton { get; } 36 | 37 | public ITransientService Transient { get; } 38 | } 39 | 40 | public class EnumerableService2 : IEnumerableService 41 | { 42 | public EnumerableService2(ITransientService transient, ISingletonService singleton) 43 | { 44 | Transient = transient; 45 | Singleton = singleton; 46 | } 47 | 48 | public ISingletonService Singleton { get; } 49 | 50 | public ITransientService Transient { get; } 51 | } 52 | 53 | public class EnumerableService3 : IEnumerableService 54 | { 55 | public EnumerableService3(ITransientService transient, ISingletonService singleton) 56 | { 57 | Transient = transient; 58 | Singleton = singleton; 59 | } 60 | 61 | public ISingletonService Singleton { get; } 62 | 63 | public ITransientService Transient { get; } 64 | } 65 | 66 | public class EnumerableService4 : IEnumerableService 67 | { 68 | public EnumerableService4(ITransientService transient, ISingletonService singleton) 69 | { 70 | Transient = transient; 71 | Singleton = singleton; 72 | } 73 | 74 | public ISingletonService Singleton { get; } 75 | 76 | public ITransientService Transient { get; } 77 | } 78 | 79 | public class EnumerableService5 : IEnumerableService 80 | { 81 | public EnumerableService5(ITransientService transient, ISingletonService singleton) 82 | { 83 | Transient = transient; 84 | Singleton = singleton; 85 | } 86 | 87 | public ISingletonService Singleton { get; } 88 | 89 | public ITransientService Transient { get; } 90 | } 91 | 92 | public interface IImportEnumerableService 93 | { 94 | IEnumerable Services { get; } 95 | } 96 | 97 | public class ImportEnumerableService : IImportEnumerableService 98 | { 99 | public ImportEnumerableService(IEnumerable services) 100 | { 101 | Services = services; 102 | } 103 | 104 | public IEnumerable Services { get; } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/FieldInjectionClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DotNet.DependencyInjectionBenchmarks.Classes 6 | { 7 | public class FieldInjectionService 8 | { 9 | public ITransientService TransientService; 10 | 11 | public ISingletonService SingletonService; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/GenericObjectClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DotNet.DependencyInjectionBenchmarks.Classes 6 | { 7 | public interface IGenericObjectService 8 | { 9 | T Value { get; } 10 | } 11 | 12 | public class GenericObjectService : IGenericObjectService 13 | { 14 | public GenericObjectService(T value) 15 | { 16 | Value = value; 17 | } 18 | 19 | public T Value { get; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/ImportMultipleSmallObjectClasses.cs: -------------------------------------------------------------------------------- 1 | namespace DotNet.DependencyInjectionBenchmarks.Classes 2 | { 3 | public interface IImportMultipleSmallObject 4 | { 5 | ISmallObjectService SmallObject1 { get; } 6 | 7 | ISmallObjectService SmallObject2 { get; } 8 | } 9 | 10 | public class ImportMultipleSmallObject : IImportMultipleSmallObject 11 | { 12 | public ImportMultipleSmallObject(ISmallObjectService smallObject1, ISmallObjectService smallObject2) 13 | { 14 | SmallObject1 = smallObject1; 15 | SmallObject2 = smallObject2; 16 | } 17 | 18 | public ISmallObjectService SmallObject1 { get; } 19 | 20 | public ISmallObjectService SmallObject2 { get; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/LargeObjectClasses.cs: -------------------------------------------------------------------------------- 1 | namespace DotNet.DependencyInjectionBenchmarks.Classes 2 | { 3 | #region interfaces 4 | public interface ILargeSingletonService1 5 | { 6 | int IntValue { get; } 7 | } 8 | 9 | public interface ILargeSingletonService2 10 | { 11 | int IntValue { get; } 12 | } 13 | 14 | public interface ILargeSingletonService3 15 | { 16 | int IntValue { get; } 17 | } 18 | 19 | public interface ILargeTransient1 20 | { 21 | int IntValue { get; } 22 | } 23 | 24 | public interface ILargeTransient2 25 | { 26 | int IntValue { get; } 27 | } 28 | 29 | public interface ILargeTransient3 30 | { 31 | int IntValue { get; } 32 | } 33 | 34 | public interface ILargeObjectService1 35 | { 36 | ILargeTransient1 Transient { get; } 37 | 38 | ILargeSingletonService1 Singleton { get; } 39 | } 40 | 41 | public interface ILargeObjectService2 42 | { 43 | ILargeTransient2 Transient { get; } 44 | 45 | ILargeSingletonService2 Singleton { get; } 46 | } 47 | 48 | public interface ILargeObjectService3 49 | { 50 | ILargeTransient3 Transient { get; } 51 | 52 | ILargeSingletonService3 Singleton { get; } 53 | } 54 | 55 | public interface ILargeComplexService 56 | { 57 | ILargeObjectService1 Service1 { get; } 58 | 59 | ILargeObjectService1 Service2 { get; } 60 | 61 | ILargeObjectService1 Service3 { get; } 62 | } 63 | #endregion 64 | 65 | #region Classes 66 | 67 | public class LargeSingletonService1 : ILargeSingletonService1 68 | { 69 | public int IntValue { get; set; } 70 | } 71 | 72 | public class LargeSingletonService2 : ILargeSingletonService2 73 | { 74 | public int IntValue { get; set; } 75 | } 76 | 77 | public class LargeSingletonService3 : ILargeSingletonService3 78 | { 79 | public int IntValue { get; set; } 80 | } 81 | 82 | public class LargeTransient1 : ILargeTransient1 83 | { 84 | public int IntValue { get; set; } 85 | } 86 | 87 | public class LargeTransient2 : ILargeTransient2 88 | { 89 | public int IntValue { get; set; } 90 | } 91 | 92 | public class LargeTransient3 : ILargeTransient3 93 | { 94 | public int IntValue { get; set; } 95 | } 96 | 97 | public class LargeObjectService1 : ILargeObjectService1 98 | { 99 | public LargeObjectService1(ILargeTransient1 transient, ILargeSingletonService1 singleton) 100 | { 101 | Transient = transient; 102 | Singleton = singleton; 103 | } 104 | 105 | public ILargeTransient1 Transient { get; } 106 | 107 | public ILargeSingletonService1 Singleton { get; } 108 | } 109 | 110 | public class LargeObjectService2 : ILargeObjectService2 111 | { 112 | public LargeObjectService2(ILargeTransient2 transient, ILargeSingletonService2 singleton) 113 | { 114 | Transient = transient; 115 | Singleton = singleton; 116 | } 117 | 118 | public ILargeTransient2 Transient { get; } 119 | 120 | public ILargeSingletonService2 Singleton { get; } 121 | } 122 | 123 | public class LargeObjectService3 : ILargeObjectService3 124 | { 125 | public LargeObjectService3(ILargeTransient3 transient, ILargeSingletonService3 singleton) 126 | { 127 | Transient = transient; 128 | Singleton = singleton; 129 | } 130 | 131 | public ILargeTransient3 Transient { get; } 132 | 133 | public ILargeSingletonService3 Singleton { get; } 134 | } 135 | 136 | public class LargeComplexService : ILargeComplexService 137 | { 138 | public LargeComplexService(ILargeObjectService1 service1, ILargeObjectService1 service2, ILargeObjectService1 service3) 139 | { 140 | Service1 = service1; 141 | Service2 = service2; 142 | Service3 = service3; 143 | } 144 | 145 | public ILargeObjectService1 Service1 { get; } 146 | 147 | public ILargeObjectService1 Service2 { get; } 148 | 149 | public ILargeObjectService1 Service3 { get; } 150 | } 151 | #endregion 152 | } 153 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/MetadataClasses.cs: -------------------------------------------------------------------------------- 1 | namespace DotNet.DependencyInjectionBenchmarks.Classes 2 | { 3 | public class MetadataClass 4 | { 5 | public int IntProp { get; set; } 6 | 7 | public double DoubleProp { get; set; } 8 | 9 | public string StringProp { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/MethodInjectionClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DotNet.DependencyInjectionBenchmarks.Classes 6 | { 7 | public interface IMethodInjectionService 8 | { 9 | ITransientService TransientService { get; } 10 | 11 | ISingletonService SingletonService { get; } 12 | } 13 | 14 | public class MethodInjectionService : IMethodInjectionService 15 | { 16 | public ITransientService TransientService { get; private set; } 17 | 18 | public ISingletonService SingletonService { get; private set; } 19 | 20 | public void InjectionMethod(ITransientService transientService, ISingletonService singletonService) 21 | { 22 | TransientService = transientService; 23 | SingletonService = singletonService; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/OneArgClasses.cs: -------------------------------------------------------------------------------- 1 | namespace DotNet.DependencyInjectionBenchmarks.Classes 2 | { 3 | public interface IOneArgeFactoryService 4 | { 5 | ISmallObjectService SmallObject { get; } 6 | } 7 | 8 | public class OneArgeFactoryService : IOneArgeFactoryService 9 | { 10 | public OneArgeFactoryService(ISmallObjectService smallObject) 11 | { 12 | SmallObject = smallObject; 13 | } 14 | 15 | public ISmallObjectService SmallObject { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/PropertyInjectionClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DotNet.DependencyInjectionBenchmarks.Classes 6 | { 7 | public interface IPropertyInjectionService 8 | { 9 | ITransientService TransientService { get; } 10 | 11 | ISingletonService SingletonService { get; } 12 | } 13 | 14 | public class PropertyInjectionService : IPropertyInjectionService 15 | { 16 | public ITransientService TransientService { get; set; } 17 | 18 | public ISingletonService SingletonService { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/SingletonService.cs: -------------------------------------------------------------------------------- 1 | namespace DotNet.DependencyInjectionBenchmarks.Classes 2 | { 3 | public interface ISingletonService 4 | { 5 | 6 | } 7 | 8 | public class SingletonService : ISingletonService 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/SmallObjectGraphService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using DotNet.DependencyInjectionBenchmarks.Containers; 3 | 4 | namespace DotNet.DependencyInjectionBenchmarks.Classes 5 | { 6 | public static class SmallObjectServices 7 | { 8 | public static IEnumerable Definitions(RegistrationLifestyle lifestyle = RegistrationLifestyle.Transient, object lifestyleInfo = null) 9 | { 10 | yield return new RegistrationDefinition { ExportType = typeof(ISingletonService), ActivationType = typeof(SingletonService), RegistrationLifestyle = RegistrationLifestyle.Singleton }; 11 | yield return new RegistrationDefinition { ExportType = typeof(ISmallObjectService), ActivationType = typeof(SmallObjectService), RegistrationLifestyle = lifestyle, LifestyleInformation = lifestyleInfo }; 12 | yield return new RegistrationDefinition { ExportType = typeof(ITransientService), ActivationType = typeof(TransientService) }; 13 | } 14 | } 15 | 16 | public interface ISmallObjectService 17 | { 18 | ITransientService TransientService { get; } 19 | 20 | ISingletonService Singleton { get; } 21 | } 22 | 23 | public class SmallObjectService : ISmallObjectService 24 | { 25 | public SmallObjectService(ITransientService transientService, ISingletonService singleton) 26 | { 27 | TransientService = transientService; 28 | Singleton = singleton; 29 | } 30 | 31 | public ITransientService TransientService { get; } 32 | 33 | public ISingletonService Singleton { get; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/ThreeArgRefService.cs: -------------------------------------------------------------------------------- 1 | namespace DotNet.DependencyInjectionBenchmarks.Classes 2 | { 3 | #region Interfaces 4 | public interface IThreeArgTransient1 5 | { 6 | 7 | } 8 | 9 | public interface IThreeArgTransient2 10 | { 11 | 12 | } 13 | 14 | public interface IThreeArgTransient3 15 | { 16 | 17 | } 18 | 19 | public interface IThreeArgRefService 20 | { 21 | IThreeArgTransient1 Transient1 { get; } 22 | 23 | IThreeArgTransient2 Transient2 { get; } 24 | 25 | IThreeArgTransient3 Transient3 { get; } 26 | } 27 | #endregion 28 | 29 | #region Impl 30 | 31 | public class ThreeArgTransient1 : IThreeArgTransient1 32 | { 33 | 34 | } 35 | 36 | public class ThreeArgTransient2 : IThreeArgTransient2 37 | { 38 | 39 | } 40 | 41 | public class ThreeArgTransient3 : IThreeArgTransient3 42 | { 43 | 44 | } 45 | 46 | public class ThreeArgRefService : IThreeArgRefService 47 | { 48 | public ThreeArgRefService(IThreeArgTransient1 transient1, IThreeArgTransient2 transient2, IThreeArgTransient3 transient3) 49 | { 50 | Transient1 = transient1; 51 | Transient2 = transient2; 52 | Transient3 = transient3; 53 | } 54 | 55 | public IThreeArgTransient1 Transient1 { get; } 56 | 57 | public IThreeArgTransient2 Transient2 { get; } 58 | 59 | public IThreeArgTransient3 Transient3 { get; } 60 | } 61 | 62 | #endregion 63 | } 64 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/ThreeArgService.cs: -------------------------------------------------------------------------------- 1 | namespace DotNet.DependencyInjectionBenchmarks.Classes 2 | { 3 | public interface IThreeArgService1 4 | { 5 | int IntValue { get; } 6 | 7 | string StringValue { get; } 8 | 9 | ITransientService TransientService { get; } 10 | } 11 | 12 | public class ThreeArgService1 : IThreeArgService1 13 | { 14 | public ThreeArgService1(int intValue, string stringValue, ITransientService transientService) 15 | { 16 | IntValue = intValue; 17 | StringValue = stringValue; 18 | TransientService = transientService; 19 | } 20 | 21 | public int IntValue { get; } 22 | 23 | public string StringValue { get; } 24 | 25 | public ITransientService TransientService { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Classes/TransientService.cs: -------------------------------------------------------------------------------- 1 | namespace DotNet.DependencyInjectionBenchmarks.Classes 2 | { 3 | public interface ITransientService 4 | { 5 | 6 | } 7 | 8 | public class TransientService : ITransientService 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/AutofacContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using Autofac; 5 | using Autofac.Builder; 6 | using Autofac.Core; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Containers 9 | { 10 | public class AutofacContainer : IContainer 11 | { 12 | private Autofac.IContainer _container; 13 | private readonly ContainerBuilder _builder = new ContainerBuilder(); 14 | 15 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 16 | public void Dispose() 17 | { 18 | _container.Dispose(); 19 | } 20 | 21 | public class AutofacScope : IResolveScope 22 | { 23 | private readonly ILifetimeScope _lifetimeScope; 24 | 25 | public AutofacScope(ILifetimeScope lifetimeScope) 26 | { 27 | _lifetimeScope = lifetimeScope; 28 | } 29 | 30 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 31 | public void Dispose() 32 | { 33 | _lifetimeScope.Dispose(); 34 | } 35 | 36 | public IResolveScope CreateScope(string scopeName = "") 37 | { 38 | return new AutofacScope(_lifetimeScope.BeginLifetimeScope(scopeName)); 39 | } 40 | 41 | public object Resolve(Type type) 42 | { 43 | return _lifetimeScope.Resolve(type); 44 | } 45 | 46 | public object Resolve(Type type, object data) 47 | { 48 | var array = data as Array; 49 | 50 | if (array != null) 51 | { 52 | var parameters = new List(); 53 | 54 | foreach (var dataValue in array) 55 | { 56 | parameters.Add(new TypedParameter(dataValue.GetType(), dataValue)); 57 | } 58 | 59 | return _lifetimeScope.Resolve(type, parameters); 60 | } 61 | 62 | throw new NotSupportedException("Data must be array"); 63 | } 64 | 65 | public bool TryResolve(Type type, object data, out object value) 66 | { 67 | return _lifetimeScope.TryResolve(type, out value); 68 | } 69 | } 70 | 71 | public IResolveScope CreateScope(string scopeName = "") 72 | { 73 | return new AutofacScope(_container.BeginLifetimeScope(scopeName)); 74 | } 75 | 76 | public object Resolve(Type type) 77 | { 78 | return _container.Resolve(type); 79 | } 80 | 81 | public object Resolve(Type type, object data) 82 | { 83 | var array = data as Array; 84 | 85 | if (array != null) 86 | { 87 | var parameters = new List(); 88 | 89 | foreach (var dataValue in array) 90 | { 91 | parameters.Add(new TypedParameter(dataValue.GetType(), dataValue)); 92 | } 93 | 94 | return _container.Resolve(type, parameters); 95 | } 96 | 97 | throw new NotSupportedException("Data must be array"); 98 | } 99 | 100 | public bool TryResolve(Type type, object data, out object value) 101 | { 102 | return _container.TryResolve(type, out value); 103 | } 104 | 105 | public string DisplayName => "Autofac"; 106 | 107 | public string Version => typeof(Autofac.IContainer).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 108 | 109 | public string WebSite => "https://github.com/autofac/Autofac"; 110 | 111 | public void BuildContainer() 112 | { 113 | _container = _builder.Build(); 114 | } 115 | 116 | public void Registration(IEnumerable definitions) 117 | { 118 | foreach (var definition in definitions) 119 | { 120 | if (!definition.ExportType.GetTypeInfo().IsGenericTypeDefinition) 121 | { 122 | ProcessNonGenericRegistration(definition); 123 | } 124 | else 125 | { 126 | ProcessOpenGenericRegistration(definition); 127 | } 128 | } 129 | } 130 | 131 | private void ProcessOpenGenericRegistration(RegistrationDefinition definition) 132 | { 133 | var registration = _builder.RegisterGeneric(definition.ActivationType); 134 | 135 | ProcessRegistrationDefinition(definition, registration); 136 | } 137 | 138 | private void ProcessNonGenericRegistration(RegistrationDefinition definition) 139 | { 140 | var registration = _builder.RegisterType(definition.ActivationType); 141 | 142 | ProcessRegistrationDefinition(definition, registration); 143 | } 144 | 145 | private void ProcessRegistrationDefinition(RegistrationDefinition definition, 146 | IRegistrationBuilder registration) 147 | { 148 | 149 | if (definition.ExportKey == null) 150 | { 151 | registration.As(definition.ExportType); 152 | } 153 | else 154 | { 155 | registration.Keyed(definition.ExportKey, definition.ExportType); 156 | } 157 | 158 | switch (definition.RegistrationLifestyle) 159 | { 160 | case RegistrationLifestyle.Singleton: 161 | registration.SingleInstance(); 162 | break; 163 | case RegistrationLifestyle.SingletonPerScope: 164 | registration.InstancePerLifetimeScope(); 165 | break; 166 | case RegistrationLifestyle.SingletonPerNamedScope: 167 | registration.InstancePerMatchingLifetimeScope(definition.LifestyleInformation); 168 | break; 169 | } 170 | 171 | if (definition.Metadata != null) 172 | { 173 | foreach (var kvp in definition.Metadata) 174 | { 175 | registration.WithMetadata(kvp.Key.ToString(), kvp.Value); 176 | } 177 | } 178 | 179 | if (definition.MemberInjectionList != null) 180 | { 181 | foreach (var injectionInfo in definition.MemberInjectionList) 182 | { 183 | switch (injectionInfo.InjectionType) 184 | { 185 | case MemberInjectionType.Field: 186 | throw new Exception("Field injection is not supported out of the box for autofac"); 187 | 188 | case MemberInjectionType.Method: 189 | throw new Exception("Method injection is not supported out of the box for autofac"); 190 | 191 | case MemberInjectionType.Property: 192 | registration.PropertiesAutowired(); 193 | break; 194 | } 195 | } 196 | } 197 | } 198 | 199 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 200 | { 201 | var register = _builder.Register(c => factory()); 202 | 203 | switch (lifestyle) 204 | { 205 | case RegistrationLifestyle.Singleton: 206 | register.SingleInstance(); 207 | break; 208 | case RegistrationLifestyle.SingletonPerScope: 209 | register.InstancePerLifetimeScope(); 210 | break; 211 | } 212 | } 213 | 214 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 215 | { 216 | var register = _builder.Register(c => factory(c.Resolve())); 217 | 218 | switch (lifestyle) 219 | { 220 | case RegistrationLifestyle.Singleton: 221 | register.SingleInstance(); 222 | break; 223 | case RegistrationLifestyle.SingletonPerScope: 224 | register.InstancePerLifetimeScope(); 225 | break; 226 | } 227 | } 228 | 229 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 230 | { 231 | var register = _builder.Register(c => factory(c.Resolve(), c.Resolve(), c.Resolve())); 232 | 233 | switch (lifestyle) 234 | { 235 | case RegistrationLifestyle.Singleton: 236 | register.SingleInstance(); 237 | break; 238 | case RegistrationLifestyle.SingletonPerScope: 239 | register.InstancePerLifetimeScope(); 240 | break; 241 | } 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/CastleWindsorContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using Castle.MicroKernel; 6 | using Castle.MicroKernel.Lifestyle; 7 | using Castle.MicroKernel.Registration; 8 | using Castle.MicroKernel.Resolvers; 9 | using Castle.MicroKernel.Resolvers.SpecializedResolvers; 10 | using Castle.Windsor; 11 | 12 | namespace DotNet.DependencyInjectionBenchmarks.Containers 13 | { 14 | public class CastleWindsorContainer : IContainer 15 | { 16 | private WindsorContainer _container; 17 | private IKernel _kernel; 18 | 19 | public string DisplayName => "Castle Windsor"; 20 | 21 | public string Version => typeof(WindsorContainer).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 22 | 23 | public string WebSite => "https://github.com/castleproject/Windsor"; 24 | 25 | public CastleWindsorContainer() 26 | { 27 | _container = new WindsorContainer(); 28 | _kernel = _container.Kernel; 29 | 30 | _kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true)); 31 | _container.Register(Component.For().ImplementedBy()); 32 | } 33 | 34 | public void BuildContainer() 35 | { 36 | } 37 | 38 | public class CastleWindsorScope : IResolveScope 39 | { 40 | private readonly WindsorContainer _container; 41 | private IDisposable _disposable; 42 | 43 | public CastleWindsorScope(WindsorContainer container) 44 | { 45 | _container = container; 46 | _disposable = container.BeginScope(); 47 | } 48 | 49 | public void Dispose() 50 | { 51 | _disposable.Dispose(); 52 | } 53 | 54 | public IResolveScope CreateScope(string scopeName = "") 55 | { 56 | return new CastleWindsorScope(_container); 57 | } 58 | 59 | public object Resolve(Type type) 60 | { 61 | return _container.Kernel.Resolve(type); 62 | } 63 | 64 | public object Resolve(Type type, object data) 65 | { 66 | return _container.Kernel.Resolve(type, data); 67 | } 68 | 69 | public bool TryResolve(Type type, object data, out object value) 70 | { 71 | throw new NotImplementedException(); 72 | } 73 | } 74 | 75 | public IResolveScope CreateScope(string scopeName = "") 76 | { 77 | return new CastleWindsorScope(_container); 78 | } 79 | 80 | public void Dispose() 81 | { 82 | _container.Dispose(); 83 | } 84 | 85 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 86 | { 87 | switch (lifestyle) 88 | { 89 | case RegistrationLifestyle.Singleton: 90 | _container.Register(Component.For().UsingFactoryMethod(factory).LifeStyle.Singleton); 91 | break; 92 | case RegistrationLifestyle.SingletonPerScope: 93 | _container.Register(Component.For().UsingFactoryMethod(factory) 94 | .LifeStyle.Scoped()); 95 | break; 96 | case RegistrationLifestyle.Transient: 97 | _container.Register(Component.For().UsingFactoryMethod(factory).LifeStyle.Transient); 98 | break; 99 | } 100 | } 101 | 102 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 103 | { 104 | switch (lifestyle) 105 | { 106 | case RegistrationLifestyle.Singleton: 107 | _container.Register(Component.For().UsingFactoryMethod(kernel => factory(kernel.Resolve())).LifeStyle.Singleton); 108 | break; 109 | case RegistrationLifestyle.SingletonPerScope: 110 | _container.Register(Component.For().UsingFactoryMethod(kernel => factory(kernel.Resolve())) 111 | .LifeStyle.Scoped()); 112 | break; 113 | case RegistrationLifestyle.Transient: 114 | _container.Register(Component.For().UsingFactoryMethod(kernel => factory(kernel.Resolve())).LifeStyle.Transient); 115 | break; 116 | } 117 | } 118 | 119 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 120 | { 121 | switch (lifestyle) 122 | { 123 | case RegistrationLifestyle.Singleton: 124 | _container.Register(Component.For().UsingFactoryMethod(kernel => factory(kernel.Resolve(), kernel.Resolve(), kernel.Resolve())).LifeStyle.Singleton); 125 | break; 126 | case RegistrationLifestyle.SingletonPerScope: 127 | _container.Register(Component.For().UsingFactoryMethod(kernel => factory(kernel.Resolve(), kernel.Resolve(), kernel.Resolve())).LifeStyle.Scoped()); 128 | break; 129 | case RegistrationLifestyle.Transient: 130 | _container.Register(Component.For().UsingFactoryMethod(kernel => factory(kernel.Resolve(), kernel.Resolve(), kernel.Resolve())).LifeStyle.Transient); 131 | break; 132 | } 133 | } 134 | 135 | public void Registration(IEnumerable definitions) 136 | { 137 | foreach (var definition in definitions) 138 | { 139 | switch (definition.RegistrationLifestyle) 140 | { 141 | case RegistrationLifestyle.Singleton: 142 | _container.Register(Component.For(definition.ExportType).ImplementedBy(definition.ActivationType) 143 | .LifeStyle.Singleton); 144 | break; 145 | case RegistrationLifestyle.SingletonPerScope: 146 | _container.Register(Component.For(definition.ExportType).ImplementedBy(definition.ActivationType) 147 | .LifeStyle.Scoped()); 148 | break; 149 | case RegistrationLifestyle.Transient: 150 | _container.Register(Component.For(definition.ExportType).ImplementedBy(definition.ActivationType) 151 | .LifeStyle.Transient); 152 | break; 153 | case RegistrationLifestyle.SingletonPerAncestor: 154 | case RegistrationLifestyle.SingletonPerObjectGraph: 155 | var rootType = definition.LifestyleInformation as Type; 156 | _container.Register(Component.For(definition.ExportType).ImplementedBy(definition.ActivationType) 157 | .LifestyleBoundTo(resolutionStack => resolutionStack.FirstOrDefault(h => rootType.GetTypeInfo().IsAssignableFrom(h.ComponentModel.Implementation)))); 158 | break; 159 | } 160 | } 161 | } 162 | 163 | public object Resolve(Type type) 164 | { 165 | return _kernel.Resolve(type); 166 | } 167 | 168 | public object Resolve(Type type, object data) 169 | { 170 | return _kernel.Resolve(type, data); 171 | } 172 | 173 | public bool TryResolve(Type type, object data, out object value) 174 | { 175 | throw new NotImplementedException(); 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/DryIocContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using DryIoc; 5 | 6 | namespace DotNet.DependencyInjectionBenchmarks.Containers 7 | { 8 | public class DryIocContainer : IContainer 9 | { 10 | private readonly Container _container = new Container(rules => rules.WithImplicitRootOpenScope()); 11 | 12 | public string DisplayName => "DryIoc"; 13 | 14 | public string Version => typeof(Container).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 15 | 16 | public string WebSite => "https://bitbucket.org/dadhi/dryioc"; 17 | 18 | 19 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 20 | public void Dispose() 21 | { 22 | _container.Dispose(); 23 | } 24 | 25 | public class DryIocScope : IResolveScope 26 | { 27 | private readonly DryIoc.IContainer _scope; 28 | 29 | public DryIocScope(DryIoc.IContainer scope) 30 | { 31 | _scope = scope; 32 | } 33 | 34 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 35 | public void Dispose() 36 | { 37 | _scope.Dispose(); 38 | } 39 | 40 | public IResolveScope CreateScope(string scopeName = "") 41 | { 42 | var newScope = _scope.OpenScope(scopeName); 43 | 44 | return new DryIocScope(newScope); 45 | } 46 | 47 | public object Resolve(Type type) 48 | { 49 | return _scope.Resolve(type); 50 | } 51 | 52 | public object Resolve(Type type, object data) 53 | { 54 | throw new NotImplementedException(); 55 | } 56 | 57 | public bool TryResolve(Type type, object data, out object value) 58 | { 59 | value = _scope.Resolve(type, IfUnresolved.ReturnDefault); 60 | 61 | return value != null; 62 | } 63 | } 64 | 65 | public IResolveScope CreateScope(string scopeName = "") 66 | { 67 | var scope = _container.OpenScope(); 68 | 69 | return new DryIocScope(scope); 70 | } 71 | 72 | public object Resolve(Type type) 73 | { 74 | return _container.Resolve(type); 75 | } 76 | 77 | public object Resolve(Type type, object data) 78 | { 79 | throw new NotImplementedException(); 80 | } 81 | 82 | public bool TryResolve(Type type, object data, out object value) 83 | { 84 | value = _container.Resolve(type, IfUnresolved.ReturnDefault); 85 | 86 | return value != null; 87 | } 88 | 89 | public void BuildContainer() 90 | { 91 | 92 | } 93 | 94 | public void Registration(IEnumerable definitions) 95 | { 96 | foreach (var definition in definitions) 97 | { 98 | IReuse reuse = null; 99 | 100 | switch (definition.RegistrationLifestyle) 101 | { 102 | case RegistrationLifestyle.Singleton: 103 | reuse = new SingletonReuse(); 104 | break; 105 | case RegistrationLifestyle.SingletonPerScope: 106 | reuse = new CurrentScopeReuse(); 107 | break; 108 | } 109 | 110 | PropertiesAndFieldsSelector madeOf = null; 111 | 112 | if (definition.MemberInjectionList != null) 113 | { 114 | madeOf = PropertiesAndFields.Of; 115 | 116 | foreach (var injectionInfo in definition.MemberInjectionList) 117 | { 118 | switch (injectionInfo.InjectionType) 119 | { 120 | case MemberInjectionType.Field: 121 | case MemberInjectionType.Property: 122 | madeOf = madeOf.Name(injectionInfo.MemberName); 123 | break; 124 | case MemberInjectionType.Method: 125 | throw new NotSupportedException(); 126 | } 127 | } 128 | } 129 | 130 | _container.Register(definition.ExportType, definition.ActivationType, reuse, madeOf); 131 | } 132 | } 133 | 134 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 135 | { 136 | IReuse reuse = null; 137 | 138 | switch (lifestyle) 139 | { 140 | case RegistrationLifestyle.Singleton: 141 | reuse = new SingletonReuse(); 142 | break; 143 | case RegistrationLifestyle.SingletonPerScope: 144 | reuse = new CurrentScopeReuse(); 145 | break; 146 | case RegistrationLifestyle.SingletonPerObjectGraph: 147 | throw new NotSupportedException(""); 148 | } 149 | 150 | _container.RegisterDelegate(r => factory(), reuse); 151 | } 152 | 153 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 154 | { 155 | IReuse reuse = null; 156 | 157 | switch (lifestyle) 158 | { 159 | case RegistrationLifestyle.Singleton: 160 | reuse = new SingletonReuse(); 161 | break; 162 | case RegistrationLifestyle.SingletonPerScope: 163 | reuse = new CurrentScopeReuse(); 164 | break; 165 | case RegistrationLifestyle.SingletonPerObjectGraph: 166 | throw new NotSupportedException(""); 167 | } 168 | 169 | _container.RegisterDelegate(r => factory(r.Resolve()), reuse); 170 | } 171 | 172 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 173 | { 174 | IReuse reuse = null; 175 | 176 | switch (lifestyle) 177 | { 178 | case RegistrationLifestyle.Singleton: 179 | reuse = new SingletonReuse(); 180 | break; 181 | case RegistrationLifestyle.SingletonPerScope: 182 | reuse = new CurrentScopeReuse(); 183 | break; 184 | case RegistrationLifestyle.SingletonPerObjectGraph: 185 | throw new NotSupportedException(""); 186 | } 187 | 188 | _container.RegisterDelegate(r => factory(r.Resolve(), r.Resolve(), r.Resolve()), reuse); 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/GraceContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using Grace.DependencyInjection; 6 | using Grace.Dynamic; 7 | 8 | namespace DotNet.DependencyInjectionBenchmarks.Containers 9 | { 10 | public class GraceContainer : IContainer 11 | { 12 | private readonly DependencyInjectionContainer _container = new DependencyInjectionContainer(GraceDynamicMethod.Configuration()); 13 | 14 | public string DisplayName => "Grace"; 15 | 16 | public string Version => typeof(DependencyInjectionContainer).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 17 | 18 | public string WebSite => "https://github.com/ipjohnson/Grace"; 19 | 20 | public void Dispose() 21 | { 22 | _container.Dispose(); 23 | } 24 | 25 | public class GraceScope : IResolveScope 26 | { 27 | private readonly IExportLocatorScope _scope; 28 | 29 | public GraceScope(IExportLocatorScope scope) 30 | { 31 | _scope = scope; 32 | } 33 | 34 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 35 | public void Dispose() 36 | { 37 | _scope.Dispose(); 38 | } 39 | 40 | public IResolveScope CreateScope(string scopeName = "") 41 | { 42 | return new GraceScope(_scope.BeginLifetimeScope(scopeName)); 43 | } 44 | 45 | public object Resolve(Type type) 46 | { 47 | return _scope.Locate(type); 48 | } 49 | 50 | public object Resolve(Type type, object data) 51 | { 52 | return _scope.Locate(type, data); 53 | } 54 | 55 | public bool TryResolve(Type type, object data, out object value) 56 | { 57 | return _scope.TryLocate(type, out value, data); 58 | } 59 | } 60 | 61 | public IResolveScope CreateScope(string scopeName = "") 62 | { 63 | return new GraceScope(_container.BeginLifetimeScope(scopeName)); 64 | } 65 | 66 | public object Resolve(Type type) 67 | { 68 | return _container.Locate(type); 69 | } 70 | 71 | public object Resolve(Type type, object data) 72 | { 73 | return _container.Locate(type, data); 74 | } 75 | 76 | public bool TryResolve(Type type, object data, out object value) 77 | { 78 | return _container.TryLocate(type, out value, data); 79 | } 80 | 81 | public void BuildContainer() 82 | { 83 | 84 | } 85 | 86 | public void Registration(IEnumerable definitions) 87 | { 88 | _container.Configure(c => 89 | { 90 | foreach (var definition in definitions) 91 | { 92 | var export = c.Export(definition.ActivationType); 93 | 94 | if (definition.ExportKey == null) 95 | { 96 | export.As(definition.ExportType); 97 | } 98 | else 99 | { 100 | export.AsKeyed(definition.ExportType, definition.ExportKey); 101 | } 102 | 103 | switch (definition.RegistrationLifestyle) 104 | { 105 | case RegistrationLifestyle.Singleton: 106 | export.Lifestyle.Singleton(); 107 | break; 108 | case RegistrationLifestyle.SingletonPerScope: 109 | export.Lifestyle.SingletonPerScope(); 110 | break; 111 | case RegistrationLifestyle.SingletonPerObjectGraph: 112 | export.Lifestyle.SingletonPerObjectGraph(); 113 | break; 114 | case RegistrationLifestyle.SingletonPerNamedScope: 115 | export.Lifestyle.SingletonPerNamedScope(definition.LifestyleInformation as string); 116 | break; 117 | case RegistrationLifestyle.SingletonPerAncestor: 118 | export.Lifestyle.SingletonPerAncestor(definition.LifestyleInformation as Type); 119 | break; 120 | } 121 | 122 | if (definition.Metadata != null) 123 | { 124 | foreach (var kvp in definition.Metadata) 125 | { 126 | export.WithMetadata(kvp.Key, kvp.Value); 127 | } 128 | } 129 | 130 | if (definition.MemberInjectionList != null) 131 | { 132 | var memberList = definition.MemberInjectionList; 133 | 134 | export.ImportMembers(m => memberList.Any(mem => mem.MemberName == m.Name)); 135 | } 136 | } 137 | }); 138 | } 139 | 140 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 141 | { 142 | _container.Configure(c => 143 | { 144 | var export = c.ExportFactory(factory); 145 | 146 | switch (lifestyle) 147 | { 148 | case RegistrationLifestyle.Singleton: 149 | export.Lifestyle.Singleton(); 150 | break; 151 | case RegistrationLifestyle.SingletonPerScope: 152 | export.Lifestyle.SingletonPerScope(); 153 | break; 154 | case RegistrationLifestyle.SingletonPerObjectGraph: 155 | export.Lifestyle.SingletonPerObjectGraph(); 156 | break; 157 | } 158 | }); 159 | } 160 | 161 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 162 | { 163 | _container.Configure(c => 164 | { 165 | var export = c.ExportFactory(factory); 166 | 167 | switch (lifestyle) 168 | { 169 | case RegistrationLifestyle.Singleton: 170 | export.Lifestyle.Singleton(); 171 | break; 172 | case RegistrationLifestyle.SingletonPerScope: 173 | export.Lifestyle.SingletonPerScope(); 174 | break; 175 | case RegistrationLifestyle.SingletonPerObjectGraph: 176 | export.Lifestyle.SingletonPerObjectGraph(); 177 | break; 178 | } 179 | }); 180 | } 181 | 182 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 183 | { 184 | _container.Configure(c => 185 | { 186 | var export = c.ExportFactory(factory); 187 | 188 | switch (lifestyle) 189 | { 190 | case RegistrationLifestyle.Singleton: 191 | export.Lifestyle.Singleton(); 192 | break; 193 | case RegistrationLifestyle.SingletonPerScope: 194 | export.Lifestyle.SingletonPerScope(); 195 | break; 196 | case RegistrationLifestyle.SingletonPerObjectGraph: 197 | export.Lifestyle.SingletonPerObjectGraph(); 198 | break; 199 | } 200 | }); 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/IContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace DotNet.DependencyInjectionBenchmarks.Containers 5 | { 6 | public enum RegistrationMode 7 | { 8 | Single, 9 | Multiple, 10 | } 11 | 12 | public enum RegistrationLifestyle 13 | { 14 | Transient, 15 | Singleton, 16 | SingletonPerScope, 17 | SingletonPerObjectGraph, 18 | SingletonPerNamedScope, 19 | SingletonPerAncestor 20 | } 21 | 22 | public enum MemberInjectionType 23 | { 24 | Method, 25 | Field, 26 | Property 27 | } 28 | 29 | public class MemberInjectionInfo 30 | { 31 | public MemberInjectionType InjectionType { get; set; } 32 | 33 | public string MemberName { get; set; } 34 | } 35 | 36 | public class RegistrationDefinition 37 | { 38 | public Type ActivationType { get; set; } 39 | 40 | public Type ExportType { get; set; } 41 | 42 | public object ExportKey { get; set; } 43 | 44 | public RegistrationMode RegistrationMode { get; set; } = RegistrationMode.Single; 45 | 46 | public RegistrationLifestyle RegistrationLifestyle { get; set; } = RegistrationLifestyle.Transient; 47 | 48 | public object LifestyleInformation { get; set; } 49 | 50 | public Dictionary Metadata { get; set; } 51 | 52 | public List MemberInjectionList { get; set; } 53 | } 54 | 55 | public interface IResolveScope : IDisposable 56 | { 57 | IResolveScope CreateScope(string scopeName = ""); 58 | 59 | object Resolve(Type type); 60 | 61 | object Resolve(Type type, object data); 62 | 63 | bool TryResolve(Type type, object data, out object value); 64 | } 65 | 66 | public static class IResolveScopeExtensions 67 | { 68 | public static T Resolve(this IResolveScope scope) 69 | { 70 | return (T)scope.Resolve(typeof(T)); 71 | } 72 | } 73 | 74 | public interface IContainer : IResolveScope 75 | { 76 | string DisplayName { get; } 77 | 78 | string Version { get; } 79 | 80 | string WebSite { get; } 81 | 82 | void BuildContainer(); 83 | 84 | void Registration(IEnumerable definitions); 85 | 86 | void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class; 87 | 88 | void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class; 89 | 90 | void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class; 91 | } 92 | 93 | public static class ContainerScopeExtensions 94 | { 95 | public static void Register(this IContainer scope, 96 | RegistrationLifestyle lifestyle = RegistrationLifestyle.Transient) where TImplementation : TInterface 97 | { 98 | scope.Registration(new[] { new RegistrationDefinition { ExportType = typeof(TInterface), ActivationType = typeof(TImplementation) } }); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/LightInjectContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using LightInject; 5 | 6 | namespace DotNet.DependencyInjectionBenchmarks.Containers 7 | { 8 | public class LightInjectContainer : IContainer 9 | { 10 | private readonly ServiceContainer _container = new ServiceContainer(); 11 | 12 | public string DisplayName => "LightInject"; 13 | 14 | public string Version => typeof(ServiceContainer).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 15 | 16 | public string WebSite => "http://www.lightinject.net/"; 17 | 18 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 19 | public void Dispose() 20 | { 21 | _container.Dispose(); 22 | } 23 | 24 | public class LightInjectScope : IResolveScope 25 | { 26 | private Scope _scope; 27 | 28 | public LightInjectScope(Scope scope) 29 | { 30 | _scope = scope; 31 | } 32 | 33 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 34 | public void Dispose() 35 | { 36 | _scope.Dispose(); 37 | } 38 | 39 | public IResolveScope CreateScope(string scopeName = "") 40 | { 41 | return new LightInjectScope(_scope.BeginScope()); 42 | } 43 | 44 | public object Resolve(Type type) 45 | { 46 | return _scope.GetInstance(type); 47 | } 48 | 49 | public object Resolve(Type type, object data) 50 | { 51 | var array = data as object[]; 52 | 53 | if (array != null) 54 | { 55 | return _scope.GetInstance(type, array); 56 | } 57 | 58 | throw new NotSupportedException("data must be array"); 59 | } 60 | 61 | public bool TryResolve(Type type, object data, out object value) 62 | { 63 | return (value = _scope.TryGetInstance(type)) != null; 64 | } 65 | } 66 | 67 | public IResolveScope CreateScope(string scopeName = "") 68 | { 69 | var scope = _container.BeginScope(); 70 | 71 | return new LightInjectScope(scope); 72 | } 73 | 74 | public object Resolve(Type type) 75 | { 76 | return _container.GetInstance(type); 77 | } 78 | 79 | public object Resolve(Type type, object data) 80 | { 81 | var array = data as object[]; 82 | 83 | if (array != null) 84 | { 85 | return _container.GetInstance(type, array); 86 | } 87 | 88 | throw new NotSupportedException("data must be array"); 89 | } 90 | 91 | public bool TryResolve(Type type, object data, out object value) 92 | { 93 | return (value = _container.TryGetInstance(type)) != null; 94 | } 95 | 96 | public void BuildContainer() 97 | { 98 | 99 | } 100 | 101 | public void Registration(IEnumerable definitions) 102 | { 103 | foreach (var definition in definitions) 104 | { 105 | ILifetime lifetime = null; 106 | 107 | switch (definition.RegistrationLifestyle) 108 | { 109 | case RegistrationLifestyle.Singleton: 110 | lifetime = new PerContainerLifetime(); 111 | break; 112 | case RegistrationLifestyle.SingletonPerScope: 113 | lifetime = new PerScopeLifetime(); 114 | break; 115 | } 116 | 117 | if (definition.RegistrationMode == RegistrationMode.Single) 118 | { 119 | _container.Register(definition.ExportType, definition.ActivationType, lifetime); 120 | } 121 | else 122 | { 123 | _container.Register(definition.ExportType, definition.ActivationType, definition.ActivationType.Name, lifetime); 124 | } 125 | } 126 | } 127 | 128 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 129 | { 130 | var registration = _container.Register(serviceFactory => factory()); 131 | 132 | switch (lifestyle) 133 | { 134 | case RegistrationLifestyle.Singleton: 135 | registration.SetDefaultLifetime(); 136 | break; 137 | case RegistrationLifestyle.SingletonPerScope: 138 | registration.SetDefaultLifetime(); 139 | break; 140 | } 141 | } 142 | 143 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 144 | { 145 | var registration = _container.Register((serviceFactory, arg1) => factory(arg1)); 146 | 147 | switch (lifestyle) 148 | { 149 | case RegistrationLifestyle.Singleton: 150 | registration.SetDefaultLifetime(); 151 | break; 152 | case RegistrationLifestyle.SingletonPerScope: 153 | registration.SetDefaultLifetime(); 154 | break; 155 | } 156 | } 157 | 158 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 159 | { 160 | var registration = _container.Register((serviceFactory, arg1, arg2, arg3) => factory(arg1, arg2, arg3)); 161 | 162 | switch (lifestyle) 163 | { 164 | case RegistrationLifestyle.Singleton: 165 | registration.SetDefaultLifetime(); 166 | break; 167 | case RegistrationLifestyle.SingletonPerScope: 168 | registration.SetDefaultLifetime(); 169 | break; 170 | } 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/MicrosoftDependencyInjectionContainer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | 6 | namespace DotNet.DependencyInjectionBenchmarks.Containers 7 | { 8 | public class MicrosoftDependencyInjectionContainer : IContainer 9 | { 10 | private IServiceProvider _serviceProvider; 11 | private readonly IServiceCollection _serviceCollection = new ServiceCollection(); 12 | 13 | public string DisplayName => "Microsoft Dependency Injection"; 14 | 15 | public string Version => typeof(IServiceCollection).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 16 | 17 | public string WebSite => "https://github.com/aspnet/DependencyInjection"; 18 | 19 | 20 | public void BuildContainer() 21 | { 22 | _serviceProvider = _serviceCollection.BuildServiceProvider(); 23 | } 24 | 25 | public class ChildScope : IResolveScope 26 | { 27 | private IServiceProvider _serviceProvider; 28 | private IServiceScope _serviceScope; 29 | 30 | public ChildScope(IServiceScope serviceScope) 31 | { 32 | _serviceScope = serviceScope; 33 | _serviceProvider = serviceScope.ServiceProvider; 34 | } 35 | 36 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 37 | public void Dispose() 38 | { 39 | _serviceScope.Dispose(); 40 | } 41 | 42 | public IResolveScope CreateScope(string scopeName = "") 43 | { 44 | var scopeFactory = _serviceProvider.CreateScope(); 45 | 46 | return new ChildScope(scopeFactory); 47 | } 48 | 49 | public object Resolve(Type type) 50 | { 51 | return _serviceProvider.GetService(type); 52 | } 53 | 54 | public object Resolve(Type type, object data) 55 | { 56 | throw new NotImplementedException(); 57 | } 58 | 59 | public bool TryResolve(Type type, object data, out object value) 60 | { 61 | return (value = _serviceProvider.GetService(type)) != null; 62 | } 63 | } 64 | 65 | public IResolveScope CreateScope(string scopeName = "") 66 | { 67 | return new ChildScope(_serviceProvider.CreateScope()); 68 | } 69 | 70 | public void Dispose() 71 | { 72 | ((IDisposable)_serviceProvider).Dispose(); 73 | } 74 | 75 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 76 | { 77 | switch (lifestyle) 78 | { 79 | case RegistrationLifestyle.Transient: 80 | _serviceCollection.AddTransient(provider => factory()); 81 | break; 82 | case RegistrationLifestyle.Singleton: 83 | _serviceCollection.AddSingleton(provider => factory()); 84 | break; 85 | case RegistrationLifestyle.SingletonPerScope: 86 | _serviceCollection.AddScoped(provider => factory()); 87 | break; 88 | } 89 | } 90 | 91 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 92 | { 93 | switch (lifestyle) 94 | { 95 | case RegistrationLifestyle.Transient: 96 | _serviceCollection.AddTransient(provider => factory(provider.GetService())); 97 | break; 98 | case RegistrationLifestyle.Singleton: 99 | _serviceCollection.AddSingleton(provider => factory(provider.GetService())); 100 | break; 101 | case RegistrationLifestyle.SingletonPerScope: 102 | _serviceCollection.AddScoped(provider => factory(provider.GetService())); 103 | break; 104 | } 105 | } 106 | 107 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 108 | { 109 | switch (lifestyle) 110 | { 111 | case RegistrationLifestyle.Transient: 112 | _serviceCollection.AddTransient(provider => factory(provider.GetService(), provider.GetService(), provider.GetService())); 113 | break; 114 | case RegistrationLifestyle.Singleton: 115 | _serviceCollection.AddSingleton(provider => factory(provider.GetService(), provider.GetService(), provider.GetService())); 116 | break; 117 | case RegistrationLifestyle.SingletonPerScope: 118 | _serviceCollection.AddScoped(provider => factory(provider.GetService(), provider.GetService(), provider.GetService())); 119 | break; 120 | } 121 | } 122 | 123 | public void Registration(IEnumerable definitions) 124 | { 125 | foreach (var definition in definitions) 126 | { 127 | switch (definition.RegistrationLifestyle) 128 | { 129 | case RegistrationLifestyle.Singleton: 130 | _serviceCollection.AddSingleton(definition.ExportType, definition.ActivationType); 131 | break; 132 | case RegistrationLifestyle.SingletonPerScope: 133 | _serviceCollection.AddScoped(definition.ExportType, definition.ActivationType); 134 | break; 135 | case RegistrationLifestyle.Transient: 136 | _serviceCollection.AddTransient(definition.ExportType, definition.ActivationType); 137 | break; 138 | } 139 | } 140 | } 141 | 142 | public object Resolve(Type type) 143 | { 144 | return _serviceProvider.GetService(type); 145 | } 146 | 147 | public object Resolve(Type type, object data) 148 | { 149 | throw new NotImplementedException(); 150 | } 151 | 152 | public bool TryResolve(Type type, object data, out object value) 153 | { 154 | return (value = _serviceProvider.GetService(type)) != null; 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/NInjectContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using Ninject; 5 | 6 | namespace DotNet.DependencyInjectionBenchmarks.Containers 7 | { 8 | public class NInjectContainer : IContainer 9 | { 10 | private IReadOnlyKernel _kernel; 11 | private readonly KernelConfiguration _configuration = new KernelConfiguration(); 12 | 13 | public string DisplayName => "NInject"; 14 | 15 | public string Version => typeof(IReadOnlyKernel).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 16 | 17 | public string WebSite => "http://www.ninject.org/"; 18 | 19 | public void Dispose() 20 | { 21 | _kernel.Dispose(); 22 | } 23 | 24 | public IResolveScope CreateScope(string scopeName = "") 25 | { 26 | // ninject 4.0 child scope and named scopes aren't supported yet 27 | throw new NotSupportedException(); 28 | } 29 | 30 | public object Resolve(Type type) 31 | { 32 | return _kernel.Get(type); 33 | } 34 | 35 | public object Resolve(Type type, object data) 36 | { 37 | throw new NotImplementedException(); 38 | } 39 | 40 | public bool TryResolve(Type type, object data, out object value) 41 | { 42 | value = _kernel.TryGet(type); 43 | 44 | return value != null; 45 | } 46 | 47 | public void BuildContainer() 48 | { 49 | _kernel = _configuration.BuildReadonlyKernel(); 50 | } 51 | 52 | public void Registration(IEnumerable definitions) 53 | { 54 | foreach (var definition in definitions) 55 | { 56 | var binding = _configuration.Bind(definition.ExportType).To(definition.ActivationType); 57 | 58 | switch (definition.RegistrationLifestyle) 59 | { 60 | case RegistrationLifestyle.Singleton: 61 | binding.InSingletonScope(); 62 | break; 63 | case RegistrationLifestyle.Transient: 64 | binding.InTransientScope(); 65 | break; 66 | default: 67 | throw new NotSupportedException(); 68 | } 69 | 70 | if (definition.Metadata != null) 71 | { 72 | foreach (var pair in definition.Metadata) 73 | { 74 | binding.BindingConfiguration.Metadata.Set(pair.Key.ToString(), pair.Value); 75 | } 76 | } 77 | } 78 | } 79 | 80 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 81 | { 82 | var binding = _configuration.Bind().ToMethod(context => factory()); 83 | 84 | switch (lifestyle) 85 | { 86 | case RegistrationLifestyle.Singleton: 87 | binding.InSingletonScope(); 88 | break; 89 | case RegistrationLifestyle.Transient: 90 | binding.InTransientScope(); 91 | break; 92 | default: 93 | throw new NotSupportedException(); 94 | } 95 | } 96 | 97 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 98 | { 99 | var binding = _configuration.Bind().ToMethod(context => factory(context.Kernel.Get())); 100 | 101 | switch (lifestyle) 102 | { 103 | case RegistrationLifestyle.Singleton: 104 | binding.InSingletonScope(); 105 | break; 106 | case RegistrationLifestyle.Transient: 107 | binding.InTransientScope(); 108 | break; 109 | default: 110 | throw new NotSupportedException(); 111 | } 112 | } 113 | 114 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 115 | { 116 | var binding = _configuration.Bind().ToMethod(context => factory(context.Kernel.Get(), context.Kernel.Get(), context.Kernel.Get())); 117 | 118 | switch (lifestyle) 119 | { 120 | case RegistrationLifestyle.Singleton: 121 | binding.InSingletonScope(); 122 | break; 123 | case RegistrationLifestyle.Transient: 124 | binding.InTransientScope(); 125 | break; 126 | default: 127 | throw new NotSupportedException(); 128 | } 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/SimpleInjectorContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using SimpleInjector; 6 | 7 | namespace DotNet.DependencyInjectionBenchmarks.Containers 8 | { 9 | public class SimpleInjectorContainer : IContainer 10 | { 11 | private Container _container = new Container(); 12 | private List _multipleRegistrationDefinitions = new List(); 13 | 14 | public string DisplayName => "Simple Injector"; 15 | 16 | public string Version => typeof(Container).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 17 | 18 | public string WebSite => "https://simpleinjector.org/index.html"; 19 | 20 | 21 | public void BuildContainer() 22 | { 23 | var definitions = new Dictionary>(); 24 | 25 | foreach (var definition in _multipleRegistrationDefinitions) 26 | { 27 | if (!definitions.TryGetValue(definition.ExportType, out List list)) 28 | { 29 | list = new List(); 30 | 31 | definitions[definition.ExportType] = list; 32 | } 33 | 34 | list.Add(definition); 35 | } 36 | 37 | foreach (var pair in definitions) 38 | { 39 | _container.RegisterCollection(pair.Key, pair.Value.Select(r => r.ActivationType)); 40 | } 41 | } 42 | 43 | public IResolveScope CreateScope(string scopeName = "") 44 | { 45 | throw new NotImplementedException(); 46 | } 47 | 48 | public void Dispose() 49 | { 50 | _container.Dispose(); 51 | } 52 | 53 | public object Resolve(Type type) 54 | { 55 | return _container.GetInstance(type); 56 | } 57 | 58 | public object Resolve(Type type, object data) 59 | { 60 | throw new NotImplementedException(); 61 | } 62 | 63 | public bool TryResolve(Type type, object data, out object value) 64 | { 65 | var instances = _container.GetAllInstances(type); 66 | 67 | value = instances.FirstOrDefault(); 68 | 69 | return value != null; 70 | } 71 | 72 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 73 | { 74 | switch (lifestyle) 75 | { 76 | case RegistrationLifestyle.Singleton: 77 | _container.RegisterSingleton(factory); 78 | break; 79 | case RegistrationLifestyle.Transient: 80 | _container.Register(factory); 81 | break; 82 | } 83 | } 84 | 85 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 86 | { 87 | // requires t1 to be a reference type where no other containers require this 88 | throw new NotSupportedException(); 89 | } 90 | 91 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 92 | { 93 | // requires t1, t2, t3 to be a reference type where no other containers require this 94 | throw new NotSupportedException(); 95 | } 96 | 97 | public void Registration(IEnumerable definitions) 98 | { 99 | foreach (var definition in definitions) 100 | { 101 | if (definition.RegistrationMode == RegistrationMode.Multiple) 102 | { 103 | _multipleRegistrationDefinitions.Add(definition); 104 | } 105 | else 106 | { 107 | switch (definition.RegistrationLifestyle) 108 | { 109 | case RegistrationLifestyle.Singleton: 110 | _container.RegisterSingleton(definition.ExportType, definition.ActivationType); 111 | break; 112 | case RegistrationLifestyle.Transient: 113 | _container.Register(definition.ExportType, definition.ActivationType); 114 | break; 115 | } 116 | } 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Containers/StructureMapContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using StructureMap; 5 | using StructureMap.Pipeline; 6 | 7 | namespace DotNet.DependencyInjectionBenchmarks.Containers 8 | { 9 | public class StructureMapContainer : IContainer 10 | { 11 | private StructureMap.Container _container = new Container(); 12 | 13 | public string DisplayName => "StructureMap"; 14 | 15 | public string Version => typeof(Container).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.0"; 16 | 17 | public string WebSite => "http://structuremap.github.io/"; 18 | 19 | 20 | public void BuildContainer() 21 | { 22 | 23 | } 24 | 25 | public class StructureMapChildScope : IResolveScope 26 | { 27 | private StructureMap.IContainer _container; 28 | 29 | public StructureMapChildScope(StructureMap.IContainer container) 30 | { 31 | _container = container; 32 | } 33 | 34 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 35 | public void Dispose() 36 | { 37 | _container.Dispose(); 38 | } 39 | 40 | public IResolveScope CreateScope(string scopeName = "") 41 | { 42 | return new StructureMapChildScope(_container.CreateChildContainer()); 43 | } 44 | 45 | public object Resolve(Type type) 46 | { 47 | return _container.GetInstance(type); 48 | } 49 | 50 | public object Resolve(Type type, object data) 51 | { 52 | if (data is IDictionary) 53 | { 54 | return _container.GetInstance(type, new ExplicitArguments((IDictionary)data)); 55 | } 56 | 57 | throw new NotSupportedException(); 58 | } 59 | 60 | public bool TryResolve(Type type, object data, out object value) 61 | { 62 | if (data is null) 63 | { 64 | value = _container.TryGetInstance(type); 65 | 66 | return value != null; 67 | } 68 | 69 | if (data is IDictionary) 70 | { 71 | value = _container.TryGetInstance(type, new ExplicitArguments((IDictionary)data)); 72 | 73 | return value != null; 74 | } 75 | 76 | throw new NotSupportedException(); 77 | } 78 | } 79 | 80 | public IResolveScope CreateScope(string scopeName = "") 81 | { 82 | return new StructureMapChildScope(_container.CreateChildContainer()); 83 | } 84 | 85 | public void Dispose() 86 | { 87 | _container.Dispose(); 88 | } 89 | 90 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 91 | { 92 | var lifecycle = GetLifecycle(lifestyle); 93 | 94 | _container.Configure(r => r.For(lifecycle).Use(() => factory())); 95 | } 96 | 97 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 98 | { 99 | var lifecycle = GetLifecycle(lifestyle); 100 | 101 | _container.Configure(r => r.For(lifecycle).Use(context => factory(context.GetInstance()))); 102 | } 103 | 104 | public void RegisterFactory(Func factory, RegistrationMode mode, RegistrationLifestyle lifestyle) where TResult : class 105 | { 106 | var lifecycle = GetLifecycle(lifestyle); 107 | 108 | _container.Configure(r => r.For(lifecycle).Use(context => factory(context.GetInstance(), context.GetInstance(), context.GetInstance()))); 109 | } 110 | 111 | public void Registration(IEnumerable definitions) 112 | { 113 | _container.Configure(r => 114 | { 115 | foreach (var definition in definitions) 116 | { 117 | var lifecycle = GetLifecycle(definition.RegistrationLifestyle); 118 | 119 | r.For(definition.ExportType, lifecycle).Use(definition.ActivationType); 120 | } 121 | }); 122 | } 123 | 124 | private ILifecycle GetLifecycle(RegistrationLifestyle lifestyle) 125 | { 126 | ILifecycle lifecycle = null; 127 | 128 | switch (lifestyle) 129 | { 130 | case RegistrationLifestyle.Singleton: 131 | lifecycle = new SingletonLifecycle(); 132 | break; 133 | case RegistrationLifestyle.SingletonPerScope: 134 | lifecycle = new ContainerLifecycle(); 135 | break; 136 | case RegistrationLifestyle.SingletonPerObjectGraph: 137 | case RegistrationLifestyle.Transient: 138 | lifecycle = new TransientLifecycle(); 139 | break; 140 | } 141 | 142 | return lifecycle; 143 | } 144 | 145 | public object Resolve(Type type) 146 | { 147 | return _container.GetInstance(type); 148 | } 149 | 150 | public object Resolve(Type type, object data) 151 | { 152 | if (data is IDictionary) 153 | { 154 | return _container.GetInstance(type, new ExplicitArguments((IDictionary)data)); 155 | } 156 | 157 | throw new NotSupportedException(); 158 | } 159 | 160 | public bool TryResolve(Type type, object data, out object value) 161 | { 162 | if (data is null) 163 | { 164 | value = _container.TryGetInstance(type); 165 | 166 | return value != null; 167 | } 168 | 169 | if (data is IDictionary) 170 | { 171 | value = _container.TryGetInstance(type, new ExplicitArguments((IDictionary)data)); 172 | 173 | return value != null; 174 | } 175 | 176 | throw new NotSupportedException(); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/DotNet.DependencyInjectionBenchmarks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp1.1;net462 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Exporters/StreamWriterExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace DotNet.DependencyInjectionBenchmarks.Exporters 4 | { 5 | public static class StreamWriterExtensions 6 | { 7 | public static void Indent(this StreamWriter writer, int indentCount) 8 | { 9 | writer.Write(new string('\t', indentCount)); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DotNet.DependencyInjectionBenchmarks/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Reflection; 3 | using BenchmarkDotNet.Running; 4 | 5 | namespace DotNet.DependencyInjectionBenchmarks 6 | { 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | var benchmarks = 12 | typeof(Program).GetTypeInfo().Assembly.ExportedTypes.Where(t => !t.GetTypeInfo().IsAbstract && t.Name.EndsWith("Benchmark")); 13 | 14 | var switcher = new BenchmarkSwitcher(benchmarks.ToArray()); 15 | 16 | switcher.Run(args, new BenchmarkConfig()); 17 | } 18 | } 19 | } 20 | --------------------------------------------------------------------------------