Skip to content

Commit

Permalink
[ConstructorQueryProvider] Implement a class to provide a constructor…
Browse files Browse the repository at this point in the history
… query API.
  • Loading branch information
Aleksbgbg committed Jun 21, 2019
1 parent 5a8652b commit d0f05d1
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
112 changes: 112 additions & 0 deletions Wingman.Tests/DI/ConstructorQueryProviderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
namespace Wingman.Tests.DI
{
using System;
using System.Linq;
using System.Reflection;

using Moq;

using Wingman.DI;

using Xunit;

public class ConstructorQueryProviderTests
{
private readonly Mock<IConstructorFactory> _constructorFactoryMock;

private readonly ConstructorQueryProvider _constructorQueryProvider;

public ConstructorQueryProviderTests()
{
_constructorFactoryMock = new Mock<IConstructorFactory>();

_constructorQueryProvider = new ConstructorQueryProvider(_constructorFactoryMock.Object);
}

[Fact]
public void TestMapsPublicConstructor()
{
MapConstructorsOf<ServiceWithPublicConstructor>();

VerifyMakeConstructorCalled<ServiceWithPublicConstructor>(expectedConstructors: 1);
}

[Fact]
public void TestMapsMultiplePublicConstructorsAndNotHiddenOnes()
{
MapConstructorsOf<ServiceWithPublicAndHiddenConstructors>();

VerifyMakeConstructorCalled<ServiceWithPublicAndHiddenConstructors>(expectedConstructors: 3);
}

[Fact]
public void TestDoesNotMapHiddenConstructor()
{
MapConstructorsOf<ServiceWithHiddenConstructor>();

VerifyMakeConstructorCalled<ServiceWithHiddenConstructor>(expectedConstructors: 0);
}

[Fact]
public void TestDoesNotMapStaticConstructor()
{
MapConstructorsOf<ServiceWithStaticConstructor>();

VerifyMakeConstructorCalled<ServiceWithStaticConstructor>(expectedConstructors: 0);
}

private void MapConstructorsOf<T>()
{
MapConstructors(typeof(T));
}

private void MapConstructors(Type type)
{
_constructorQueryProvider.QueryPublicInstanceConstructors(type).ToArray();
}

private void VerifyMakeConstructorCalled<T>(int expectedConstructors)
{
ConstructorInfo[] constructors = typeof(T).GetConstructors();

Assert.Equal(expectedConstructors, constructors.Length);

foreach (ConstructorInfo constructor in constructors)
{
_constructorFactoryMock.Verify(factory => factory.CreateConstructor(constructor), Times.Once);
}

_constructorFactoryMock.VerifyNoOtherCalls();
}

private class ServiceWithPublicConstructor
{
public ServiceWithPublicConstructor(object _) { }
}

class ServiceWithPublicAndHiddenConstructors
{
public ServiceWithPublicAndHiddenConstructors() { }

public ServiceWithPublicAndHiddenConstructors(object _) { }

public ServiceWithPublicAndHiddenConstructors(object _, object _1) { }

internal ServiceWithPublicAndHiddenConstructors(object _, object _1, object _2) { }

private ServiceWithPublicAndHiddenConstructors(object _, object _1, object _2, object _3) { }
}

private class ServiceWithHiddenConstructor
{
internal ServiceWithHiddenConstructor(object _) { }
}

private class ServiceWithStaticConstructor
{
private ServiceWithStaticConstructor() { }

static ServiceWithStaticConstructor() { }
}
}
}
23 changes: 23 additions & 0 deletions Wingman/DI/ConstructorQueryProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Wingman.DI
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

internal class ConstructorQueryProvider : IConstructorQueryProvider
{
private readonly IConstructorFactory _constructorFactory;

public ConstructorQueryProvider(IConstructorFactory constructorFactory)
{
_constructorFactory = constructorFactory;
}

public IEnumerable<IConstructor> QueryPublicInstanceConstructors(Type type)
{
return type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)
.Select(_constructorFactory.CreateConstructor);
}
}
}
10 changes: 10 additions & 0 deletions Wingman/DI/IConstructorQueryProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Wingman.DI
{
using System;
using System.Collections.Generic;

internal interface IConstructorQueryProvider
{
IEnumerable<IConstructor> QueryPublicInstanceConstructors(Type type);
}
}

0 comments on commit d0f05d1

Please sign in to comment.