Skip to content

Commit

Permalink
Container improvements, benchmarks and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
CrackAndDie committed Feb 20, 2024
1 parent 30fda40 commit 0303cc3
Show file tree
Hide file tree
Showing 29 changed files with 757 additions and 134 deletions.
6 changes: 3 additions & 3 deletions Hypocrite.Avalonia/Container/LightContainerExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ public void FinalizeExtension()

public Type GetRegistrationType(string key)
{
return Instance.Registrations.FirstOrDefault(x => x.Name == key)?.GetType();
return Instance.Registrations.Get(0, key)?.Value?.MappedToType;
}

public Type GetRegistrationType(Type serviceType)
{
var matchingRegistration = Instance.Registrations.Where(x => x.RegisteredType == serviceType).FirstOrDefault();
return matchingRegistration?.MappedToType;
var matchingRegistration = Instance.Registrations.Get(serviceType.GetHashCode(), string.Empty);
return matchingRegistration?.Value?.MappedToType;
}

public bool IsRegistered(Type type)
Expand Down
14 changes: 14 additions & 0 deletions Hypocrite.Benchmarks/Container/ContainerTestClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Hypocrite.Benchmarks.Container
{
public class ContainerTestClass
{
public int Id { get; set; }
public string Name { get; set; }

public ContainerTestClass(int id, string name)
{
Id = id;
Name = name;
}
}
}
8 changes: 8 additions & 0 deletions Hypocrite.Benchmarks/Container/ContainerTestClass2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Hypocrite.Benchmarks.Container
{
public class ContainerTestClass2
{
public int Id { get; set; }
public string Name { get; set; }
}
}
21 changes: 21 additions & 0 deletions Hypocrite.Benchmarks/Container/ContainerTestClass3.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Hypocrite.Core.Container;
using Unity;

namespace Hypocrite.Benchmarks.Container
{
public class ContainerTestClass3Light
{
public int Id { get; set; }
public string Name { get; set; }
[Injection]
public ContainerTestClass2 TestClass { get; set; }
}

public class ContainerTestClass3Unity
{
public int Id { get; set; }
public string Name { get; set; }
[Dependency]
public ContainerTestClass2 TestClass { get; set; }
}
}
29 changes: 29 additions & 0 deletions Hypocrite.Benchmarks/Container/ContainerTestClass4.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Hypocrite.Core.Container;
using Unity;

namespace Hypocrite.Benchmarks.Container
{
public class ContainerTestClass4Light
{
public int Id { get; set; }
public string Name { get; set; }
public ContainerTestClass2 TestClass { get; set; }

public ContainerTestClass4Light([Injection] ContainerTestClass2 testClass)
{
TestClass = testClass;
}
}

public class ContainerTestClass4Unity
{
public int Id { get; set; }
public string Name { get; set; }
public ContainerTestClass2 TestClass { get; set; }

public ContainerTestClass4Unity([Dependency] ContainerTestClass2 testClass)
{
TestClass = testClass;
}
}
}
34 changes: 34 additions & 0 deletions Hypocrite.Benchmarks/Container/IsRegistered.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using BenchmarkDotNet.Attributes;
using Hypocrite.Core.Container;
using Hypocrite.Core.Container.Interfaces;
using Unity;

namespace Hypocrite.Benchmarks.Container
{
[MemoryDiagnoser]
public class IsRegistered
{
ILightContainer _lightContainer;
IUnityContainer _unityContainer;

public IsRegistered()
{
_lightContainer = new LightContainer();
_lightContainer.RegisterType(typeof(ContainerTestClass2), typeof(ContainerTestClass2));
_unityContainer = new UnityContainer();
_unityContainer.RegisterType<ContainerTestClass2>();
}

[Benchmark]
public bool WithUnityContainer()
{
return _unityContainer.IsRegistered<ContainerTestClass2>();
}

[Benchmark]
public bool WithLightContainer()
{
return _lightContainer.IsRegistered(typeof(ContainerTestClass2));
}
}
}
50 changes: 50 additions & 0 deletions Hypocrite.Benchmarks/Container/LightContainerSteps.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using BenchmarkDotNet.Attributes;
using Hypocrite.Core.Container;
using Hypocrite.Core.Container.Extensions;

namespace Hypocrite.Benchmarks.Container
{
[MemoryDiagnoser]
public class LightContainerSteps
{
LightContainer _lightContainer;

public LightContainerSteps()
{
_lightContainer = new LightContainer();
_lightContainer.RegisterType(typeof(ContainerTestClass2), typeof(ContainerTestClass2), true);
}

[Benchmark]
public void IsRegistered()
{
_lightContainer.IsRegistered(typeof(ContainerTestClass2));
}

[Benchmark]
public void GetRegistration()
{
_lightContainer.GetRegistration(typeof(ContainerTestClass2), string.Empty);
}

[Benchmark]
public void GetConstructor()
{
var _ = typeof(ContainerTestClass2).GetNormalConstructor();
}

[Benchmark]
public void CreateInstancePure()
{
var constructor = typeof(ContainerTestClass2).GetNormalConstructor();
var _ = constructor.Invoke(null);
}

[Benchmark]
public void CreateInstance()
{
var reg = _lightContainer.GetRegistration(typeof(ContainerTestClass2), string.Empty);
var _ = _lightContainer.InstanceCreator.CreateInstance(reg, _lightContainer, true);
}
}
}
35 changes: 35 additions & 0 deletions Hypocrite.Benchmarks/Container/ResolveSingleton.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using BenchmarkDotNet.Attributes;
using Hypocrite.Core.Container;
using Hypocrite.Core.Container.Interfaces;
using System.Linq.Expressions;
using Unity;

namespace Hypocrite.Benchmarks.Container
{
[MemoryDiagnoser]
public class ResolveSingleton
{
ILightContainer _lightContainer;
IUnityContainer _unityContainer;

public ResolveSingleton()
{
_lightContainer = new LightContainer();
_lightContainer.RegisterType(typeof(ContainerTestClass2), typeof(ContainerTestClass2), true);
_unityContainer = new UnityContainer();
_unityContainer.RegisterSingleton<ContainerTestClass2>();
}

[Benchmark]
public ContainerTestClass2 WithUnityContainer()
{
return _unityContainer.Resolve<ContainerTestClass2>();
}

[Benchmark]
public ContainerTestClass2 WithLightContainer()
{
return _lightContainer.Resolve(typeof(ContainerTestClass2)) as ContainerTestClass2;
}
}
}
34 changes: 34 additions & 0 deletions Hypocrite.Benchmarks/Container/ResolveType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using BenchmarkDotNet.Attributes;
using Hypocrite.Core.Container;
using Hypocrite.Core.Container.Interfaces;
using Unity;

namespace Hypocrite.Benchmarks.Container
{
[MemoryDiagnoser]
public class ResolveType
{
ILightContainer _lightContainer;
IUnityContainer _unityContainer;

public ResolveType()
{
_lightContainer = new LightContainer();
_lightContainer.RegisterType(typeof(ContainerTestClass2), typeof(ContainerTestClass2));
_unityContainer = new UnityContainer();
_unityContainer.RegisterType<ContainerTestClass2>();
}

[Benchmark]
public ContainerTestClass2 WithUnityContainer()
{
return _unityContainer.Resolve<ContainerTestClass2>();
}

[Benchmark]
public ContainerTestClass2 WithLightContainer()
{
return _lightContainer.Resolve(typeof(ContainerTestClass2)) as ContainerTestClass2;
}
}
}
36 changes: 36 additions & 0 deletions Hypocrite.Benchmarks/Container/ResolveTypeWithCtorInjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using BenchmarkDotNet.Attributes;
using Hypocrite.Core.Container;
using Hypocrite.Core.Container.Interfaces;
using Unity;

namespace Hypocrite.Benchmarks.Container
{
[MemoryDiagnoser]
public class ResolveTypeWithCtorInjection
{
ILightContainer _lightContainer;
IUnityContainer _unityContainer;

public ResolveTypeWithCtorInjection()
{
_lightContainer = new LightContainer();
_lightContainer.RegisterType(typeof(ContainerTestClass2), typeof(ContainerTestClass2));
_lightContainer.RegisterType(typeof(ContainerTestClass4Light), typeof(ContainerTestClass4Light));
_unityContainer = new UnityContainer();
_unityContainer.RegisterType<ContainerTestClass2>();
_unityContainer.RegisterType<ContainerTestClass4Unity>();
}

[Benchmark]
public int WithUnityContainer()
{
return _unityContainer.Resolve<ContainerTestClass4Unity>().TestClass.Id;
}

[Benchmark]
public int WithLightContainer()
{
return (_lightContainer.Resolve(typeof(ContainerTestClass4Light)) as ContainerTestClass4Light).TestClass.Id;
}
}
}
36 changes: 36 additions & 0 deletions Hypocrite.Benchmarks/Container/ResolveTypeWithInjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using BenchmarkDotNet.Attributes;
using Hypocrite.Core.Container;
using Hypocrite.Core.Container.Interfaces;
using Unity;

namespace Hypocrite.Benchmarks.Container
{
[MemoryDiagnoser]
public class ResolveTypeWithInjection
{
ILightContainer _lightContainer;
IUnityContainer _unityContainer;

public ResolveTypeWithInjection()
{
_lightContainer = new LightContainer();
_lightContainer.RegisterType(typeof(ContainerTestClass2), typeof(ContainerTestClass2));
_lightContainer.RegisterType(typeof(ContainerTestClass3Light), typeof(ContainerTestClass3Light));
_unityContainer = new UnityContainer();
_unityContainer.RegisterType<ContainerTestClass2>();
_unityContainer.RegisterType<ContainerTestClass3Unity>();
}

[Benchmark]
public int WithUnityContainer()
{
return _unityContainer.Resolve<ContainerTestClass3Unity>().TestClass.Id;
}

[Benchmark]
public int WithLightContainer()
{
return (_lightContainer.Resolve(typeof(ContainerTestClass3Light)) as ContainerTestClass3Light).TestClass.Id;
}
}
}
21 changes: 21 additions & 0 deletions Hypocrite.Benchmarks/Hypocrite.Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.4" />

<PackageReference Include="Unity.Container" Version="5.11.11" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Hypocrite.Core\Hypocrite.Core.csproj">
<Project>{9ACAC9D4-6F9D-4701-80F6-670B8ED30B2F}</Project>
<Name>Hypocrite.Core</Name>
</ProjectReference>
</ItemGroup>
</Project>
26 changes: 26 additions & 0 deletions Hypocrite.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Reflection;

namespace Hypocrite.Benchmarks
{
class Program
{
static void Main(string[] args)
{
// Use reflection for a more maintainable way of creating the benchmark switcher,
// Benchmarks are listed in namespace order first (e.g. BenchmarkDotNet.Samples.CPU,
// BenchmarkDotNet.Samples.IL, etc) then by name, so the output is easy to understand
var benchmarks = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.GetMethods(BindingFlags.Instance | BindingFlags.Public)
.Any(m => m.GetCustomAttributes(typeof(BenchmarkAttribute), false).Any()))
.OrderBy(t => t.Namespace)
.ThenBy(t => t.Name)
.ToArray();
var benchmarkSwitcher = new BenchmarkSwitcher(benchmarks);
benchmarkSwitcher.Run(args);

Console.ReadKey();
}
}
}
12 changes: 12 additions & 0 deletions Hypocrite.Core/Container/Common/ConstructorInjectionInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Reflection;

namespace Hypocrite.Core.Container.Common
{
public class ConstructorInjectionInfo
{
public Func<object> DefaultConstructorDelegate { get; set; }
public ConstructorInfo DefaultConstructorInfo { get; set; }
public ParameterInfo[] InjectionMembers { get; set; }
}
}
Loading

0 comments on commit 0303cc3

Please sign in to comment.