Skip to content

Commit 386e186

Browse files
authored
Feature/di separation (#3)
* First step, everything builds and apis map over Still need to do further work to split things out but this at least is a first step. * Separated out the Ninject parts Given Ninject is not actually a split container its easy enough to represent, the difficulty will come with MS style ones. * Have basic tests in place and working * Confirming exceptions * Adding basic implementation for new DI Also added some tests for testing common scenarios * Adding build pack for new packages * Updating build and api keys
1 parent 7380202 commit 386e186

42 files changed

Lines changed: 1026 additions & 337 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ deploy:
2727
APPVEYOR_REPO_TAG: true
2828
server:
2929
api_key:
30-
secure: wJrG+bs2kamc9yejb3cqEmtCGrF9IcqdyU/iApCiWSofb+y69srQF5cmt9xu30/O
30+
secure: xItHI+jcoXOw7VZoVj1gGOiH2zajMnpq0wQgXlp0SEl5PlAQ7epxowtpbqID7a4V
3131
skip_symbols: true
3232
symbol_server:
3333
artifact: /.*\.nupkg/

build/pack.bat

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
set version=5.0.0
1+
set version=7.0.0
22
dotnet pack ../src/SystemsRx.MicroRx -c Release -o ../../_dist /p:version=%version%
33
dotnet pack ../src/SystemsRx -c Release -o ../../_dist /p:version=%version%
44
dotnet pack ../src/SystemsRx.Infrastructure -c Release -o ../../_dist /p:version=%version%
55
dotnet pack ../src/SystemsRx.Plugins.Computeds -c Release -o ../../_dist /p:version=%version%
66
dotnet pack ../src/SystemsRx.Infrastructure -c Release -o ../../_dist /p:version=%version%
77
dotnet pack ../src/SystemsRx.Infrastructure.Ninject -c Release -o ../../_dist /p:version=%version%
8+
dotnet pack ../src/SystemsRx.Infrastructure.Autofac -c Release -o ../../_dist /p:version=%version%
9+
dotnet pack ../src/SystemsRx.Infrastructure.MicrosoftDependencyInjection -c Release -o ../../_dist /p:version=%version%
10+
dotnet pack ../src/SystemsRx.Infrastructure.DryIoc -c Release -o ../../_dist /p:version=%version%
811
dotnet pack ../src/SystemsRx.ReactiveData -c Release -o ../../_dist /p:version=%version%
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using SystemsRx.Infrastructure.Dependencies;
2+
using SystemsRx.Infrastructure.Extensions;
3+
using SystemsRx.Tests.Ninject.TestCode;
4+
5+
namespace SystemsRx.Tests.Ninject.Modules
6+
{
7+
public class TestModule : IDependencyModule
8+
{
9+
public void Setup(IDependencyRegistry registry)
10+
{
11+
registry.Bind<SomeTestClass>();
12+
registry.Bind<SomeTestMethodClass>(x => x.ToMethod(y => new SomeTestMethodClass()));
13+
registry.Bind<SomeDerivedTestClass>();
14+
registry.Bind<SomeBaseTestClass>(x => x.ToBoundType<SomeDerivedTestClass>());
15+
registry.Bind<ITestInterface, TestClass1>(x => x.WithName("Test1"));
16+
registry.Bind<ITestInterface, TestClass2>(x => x.WithName("Test2"));
17+
}
18+
}
19+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using SystemsRx.Executor.Handlers;
4+
using SystemsRx.Infrastructure.Autofac;
5+
using SystemsRx.Infrastructure.Dependencies;
6+
using SystemsRx.Infrastructure.DryIoc;
7+
using SystemsRx.Infrastructure.Extensions;
8+
using SystemsRx.Infrastructure.MicrosoftDependencyInjection;
9+
using SystemsRx.Infrastructure.Modules;
10+
using SystemsRx.Infrastructure.Ninject;
11+
using SystemsRx.Scheduling;
12+
using SystemsRx.Tests.Ninject.Modules;
13+
using SystemsRx.Tests.Ninject.TestCode;
14+
using Xunit;
15+
16+
namespace SystemsRx.Tests.Ninject.SanityTests
17+
{
18+
public class DependencyInjectionSanityTests
19+
{
20+
public static IEnumerable<object[]> Registries => new List<object[]>()
21+
{
22+
new object[]{new NinjectDependencyRegistry()},
23+
new object[]{new MicrosoftDependencyRegistry()},
24+
new object[]{new AutofacDependencyRegistry()},
25+
new object[]{new DryIocDependencyRegistry()},
26+
};
27+
28+
[Theory]
29+
[MemberData(nameof(Registries))]
30+
public void should_handle_test_module_bindings_correctly(IDependencyRegistry registryType)
31+
{
32+
registryType.LoadModule<TestModule>();
33+
34+
var resolver = registryType.BuildResolver();
35+
36+
var someTestClass = resolver.Resolve<SomeTestClass>();
37+
Assert.NotNull(someTestClass);
38+
39+
var someTestMethodClass = resolver.Resolve<SomeTestMethodClass>();
40+
Assert.NotNull(someTestMethodClass);
41+
42+
var someBaseTestClass = resolver.Resolve<SomeBaseTestClass>();
43+
Assert.NotNull(someBaseTestClass);
44+
Assert.IsAssignableFrom<SomeDerivedTestClass>(someBaseTestClass);
45+
46+
var testNamed1 = resolver.Resolve<ITestInterface>("Test1");
47+
Assert.NotNull(testNamed1);
48+
Assert.IsAssignableFrom<ITestInterface1>(testNamed1);
49+
Assert.IsAssignableFrom<TestClass1>(testNamed1);
50+
51+
var testNamed2 = resolver.Resolve<ITestInterface>("Test2");
52+
Assert.NotNull(testNamed2);
53+
Assert.IsAssignableFrom<ITestInterface2>(testNamed2);
54+
Assert.IsAssignableFrom<TestClass2>(testNamed2);
55+
56+
var testInterfaces = resolver.ResolveAll<ITestInterface>();
57+
Assert.NotNull(testInterfaces);
58+
59+
var testInterfaceEnumerated = testInterfaces.ToArray();
60+
Assert.NotEmpty(testInterfaceEnumerated);
61+
Assert.Equal(2, testInterfaceEnumerated.Length);
62+
Assert.True(testInterfaceEnumerated.All(x => x != null));
63+
}
64+
65+
[Theory]
66+
[MemberData(nameof(Registries))]
67+
public void should_bind_and_resolve_framework_module(IDependencyRegistry registryType)
68+
{
69+
registryType.LoadModule<FrameworkModule>();
70+
71+
var resolver = registryType.BuildResolver();
72+
var systems = resolver.ResolveAll<IConventionalSystemHandler>();
73+
Assert.NotNull(systems);
74+
Assert.NotEmpty(systems);
75+
Assert.Equal(3, systems.Count());
76+
77+
var timeTracker = resolver.Resolve<ITimeTracker>();
78+
Assert.NotNull(timeTracker);
79+
}
80+
}
81+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<IsPackable>false</IsPackable>
6+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
7+
<RootNamespace>SystemsRx.Tests.Ninject</RootNamespace>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
12+
<PackageReference Include="xunit" Version="2.7.0" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<ProjectReference Include="..\SystemsRx.Infrastructure.Autofac\SystemsRx.Infrastructure.Autofac.csproj" />
17+
<ProjectReference Include="..\SystemsRx.Infrastructure.DryIoc\SystemsRx.Infrastructure.DryIoc.csproj" />
18+
<ProjectReference Include="..\SystemsRx.Infrastructure.MicrosoftDependencyInjection\SystemsRx.Infrastructure.MicrosoftDependencyInjection.csproj" />
19+
<ProjectReference Include="..\SystemsRx.Infrastructure.Ninject\SystemsRx.Infrastructure.Ninject.csproj" />
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace SystemsRx.Tests.Ninject.TestCode
2+
{
3+
public interface ITestInterface
4+
{
5+
6+
}
7+
8+
public interface ITestInterface1 : ITestInterface
9+
{
10+
11+
}
12+
13+
public interface ITestInterface2 : ITestInterface
14+
{
15+
16+
}
17+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
namespace SystemsRx.Tests.Ninject.TestCode
2+
{
3+
public class SomeTestClass
4+
{
5+
6+
}
7+
8+
public class SomeTestMethodClass
9+
{
10+
11+
}
12+
13+
public class SomeBaseTestClass
14+
{
15+
16+
}
17+
18+
public class SomeDerivedTestClass : SomeBaseTestClass
19+
{
20+
21+
}
22+
23+
public class TestClass1 : ITestInterface1
24+
{
25+
26+
}
27+
28+
public class TestClass2 : ITestInterface2
29+
{
30+
31+
}
32+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.1</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
</PropertyGroup>
7+
8+
<PropertyGroup>
9+
<TargetFramework>netcoreapp3.1</TargetFramework>
10+
<IsPackable>false</IsPackable>
11+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
12+
<RootNamespace>SystemsRx.Tests.MicrosoftDependencyInjection</RootNamespace>
13+
</PropertyGroup>
14+
15+
<ItemGroup>
16+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
17+
<PackageReference Include="xunit" Version="2.7.0" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<ProjectReference Include="..\SystemsRx.Infrastructure.MicrosoftDependencyInjection\SystemsRx.Infrastructure.MicrosoftDependencyInjection.csproj" />
22+
</ItemGroup>
23+
24+
<ItemGroup>
25+
<ProjectReference Include="..\SystemsRx.Infrastructure.MicrosoftDependencyInjection\SystemsRx.Infrastructure.MicrosoftDependencyInjection.csproj" />
26+
</ItemGroup>
27+
28+
<ItemGroup>
29+
<Folder Include="SanityTests\" />
30+
</ItemGroup>
31+
32+
33+
</Project>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System;
2+
using Autofac;
3+
using Autofac.Core;
4+
using SystemsRx.Infrastructure.Dependencies;
5+
6+
namespace SystemsRx.Infrastructure.Autofac
7+
{
8+
/// <summary>
9+
/// This is an autofac implementation for the dependency registry.
10+
/// </summary>
11+
public class AutofacDependencyRegistry : IDependencyRegistry
12+
{
13+
private readonly ContainerBuilder _containerBuilder;
14+
private IDependencyResolver _resolver;
15+
public object NativeRegistry => _containerBuilder;
16+
17+
public AutofacDependencyRegistry(ContainerBuilder containerBuilder = null)
18+
{
19+
_containerBuilder = containerBuilder ?? new ContainerBuilder();
20+
}
21+
22+
public void Bind(Type fromType, Type toType, BindingConfiguration configuration = null)
23+
{
24+
if (configuration == null)
25+
{
26+
_containerBuilder.RegisterType(toType).As(fromType);
27+
return;
28+
}
29+
30+
if (configuration.ToInstance != null)
31+
{
32+
var builder = _containerBuilder.RegisterInstance(configuration.ToInstance).As(fromType);
33+
34+
if(!string.IsNullOrEmpty(configuration.WithName))
35+
{ builder.Named(configuration.WithName, fromType); }
36+
37+
builder.ExternallyOwned();
38+
}
39+
else if (configuration.ToMethod != null)
40+
{
41+
var builder = _containerBuilder.Register(x => configuration.ToMethod(_resolver)).As(fromType);
42+
43+
if(!string.IsNullOrEmpty(configuration.WithName))
44+
{ builder.Named(configuration.WithName, fromType); }
45+
46+
if (configuration.AsSingleton)
47+
{ builder.SingleInstance(); }
48+
else
49+
{ builder.InstancePerDependency(); }
50+
}
51+
else
52+
{
53+
var builder = _containerBuilder.RegisterType(toType).As(fromType);
54+
55+
if(!string.IsNullOrEmpty(configuration.WithName))
56+
{ builder.Named(configuration.WithName, fromType); }
57+
58+
if (configuration.AsSingleton)
59+
{ builder.SingleInstance(); }
60+
else
61+
{ builder.InstancePerDependency(); }
62+
}
63+
}
64+
65+
public void Bind(Type type, BindingConfiguration configuration = null)
66+
{ Bind(type, type, configuration); }
67+
68+
public bool HasBinding(Type type, string name = null)
69+
{ return _containerBuilder.ComponentRegistryBuilder.IsRegistered(new TypedService(type)); }
70+
71+
public void Unbind(Type type)
72+
{
73+
// This seems unsupported in autofac
74+
}
75+
76+
public void LoadModule(IDependencyModule module)
77+
{ module.Setup(this); }
78+
79+
public IDependencyResolver BuildResolver()
80+
{
81+
var container = _containerBuilder.Build();
82+
_resolver = new AutofacDependencyResolver(container);
83+
return _resolver;
84+
}
85+
86+
public void Dispose()
87+
{
88+
// Nothing to dispose
89+
}
90+
}
91+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using Autofac;
5+
using SystemsRx.Infrastructure.Dependencies;
6+
7+
namespace SystemsRx.Infrastructure.Autofac
8+
{
9+
/// <summary>
10+
/// This is a autofac di implementation for the dependency resolver
11+
/// </summary>
12+
public class AutofacDependencyResolver : IDependencyResolver
13+
{
14+
private readonly IContainer _container;
15+
16+
public object NativeResolver => _container;
17+
18+
public AutofacDependencyResolver(IContainer container)
19+
{ _container = container; }
20+
21+
public IEnumerable ResolveAll(Type type)
22+
{
23+
var enumerableType = typeof(IEnumerable<>).MakeGenericType(type);
24+
var services = _container.Resolve(enumerableType) as IEnumerable;
25+
return services;
26+
}
27+
28+
public object Resolve(Type type, string name = null)
29+
{ return string.IsNullOrEmpty(name) ? _container.Resolve(type) : _container.ResolveNamed(name, type); }
30+
31+
public void Dispose()
32+
{ _container.Dispose(); }
33+
}
34+
}

0 commit comments

Comments
 (0)