Skip to content

Commit

Permalink
Refactoring TypeDiscoverer a bit to accommodate new needs + changing …
Browse files Browse the repository at this point in the history
…signatures

Basically we are going to need to be able to find types from any enumerable of types. TypeDiscoverer had a bunch of this functionality we wanted but coupled together with how it wants to do things. Extracting out the finding of types part into its own ITypeFinder enables us to reuse the finding bits.

Worth mentioning is that all signatures returning arrays of Type are now returning IEnumerable<Type> instead. This affected some implementations!
  • Loading branch information
einari committed May 9, 2015
1 parent e36c383 commit 3e787da
Show file tree
Hide file tree
Showing 27 changed files with 452 additions and 161 deletions.
6 changes: 6 additions & 0 deletions Source/Bifrost.Silverlight/Bifrost.Silverlight.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,9 @@
<Compile Include="..\Bifrost\Execution\ITypeDiscoverer.cs">
<Link>Execution\ITypeDiscoverer.cs</Link>
</Compile>
<Compile Include="..\Bifrost\Execution\ITypeFinder.cs">
<Link>Execution\ITypeFinder.cs</Link>
</Compile>
<Compile Include="..\Bifrost\Execution\ITypeImporter.cs">
<Link>Execution\ITypeImporter.cs</Link>
</Compile>
Expand All @@ -644,6 +647,9 @@
<Compile Include="..\Bifrost\Execution\TypeDiscoverer.cs">
<Link>Execution\TypeDiscoverer.cs</Link>
</Compile>
<Compile Include="..\Bifrost\Execution\TypeFinder.cs">
<Link>Execution\TypeFinder.cs</Link>
</Compile>
<Compile Include="..\Bifrost\Execution\TypeImporter.cs">
<Link>Execution\TypeImporter.cs</Link>
</Compile>
Expand Down
8 changes: 7 additions & 1 deletion Source/Bifrost.Specs/Bifrost.Specs.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,13 @@
<Compile Include="Execution\for_InstancesOf\when_having_multiple_implementations.cs" />
<Compile Include="Execution\for_TypeDiscoverer\when_finding_type_by_name_that_does_not_exist.cs" />
<Compile Include="Execution\for_TypeDiscoverer\when_finding_type_by_name_that_exists.cs" />
<Compile Include="Execution\for_TypeFinder\given\a_type_finder.cs" />
<Compile Include="Execution\for_TypeFinder\Stubs.cs" />
<Compile Include="Execution\for_TypeFinder\when_finding_types_with_multiple_implementations.cs" />
<Compile Include="Execution\for_TypeFinder\when_finding_types_with_multiple_implementations_but_asking_for_a_single.cs" />
<Compile Include="Execution\for_TypeFinder\when_finding_types_with_only_one_implementation.cs" />
<Compile Include="Execution\for_TypeFinder\when_finding_type_by_name_that_does_not_exist.cs" />
<Compile Include="Execution\for_TypeFinder\when_finding_type_by_name_that_exists.cs" />
<Compile Include="Execution\for_WeakDelegate\ClassWithMethod.cs" />
<Compile Include="Execution\for_WeakDelegate\DerivedImplementation.cs" />
<Compile Include="Execution\for_WeakDelegate\Implementation.cs" />
Expand Down Expand Up @@ -722,7 +729,6 @@
<Compile Include="Execution\for_TypeDiscoverer\given\a_type_discoverer.cs" />
<Compile Include="Execution\for_TypeDiscoverer\Stubs.cs" />
<Compile Include="Execution\for_TypeDiscoverer\when_finding_types_with_multiple_implementations.cs" />
<Compile Include="Execution\for_TypeDiscoverer\when_finding_types_with_multiple_implementations_but_asking_for_a_single.cs" />
<Compile Include="Execution\for_TypeDiscoverer\when_finding_types_with_only_one_implementation.cs" />
<Compile Include="Execution\for_TypeImporter\given\a_type_importer.cs" />
<Compile Include="Execution\for_TypeImporter\Stubs.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.Reflection;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using Bifrost.Execution;
using Machine.Specifications;
using Moq;
Expand All @@ -7,14 +10,32 @@ namespace Bifrost.Specs.Execution.for_TypeDiscoverer.given
{
public class a_type_discoverer
{
protected static TypeDiscoverer TypeDiscoverer;
protected static TypeDiscoverer type_discoverer;
protected static Mock<_Assembly> assembly_mock;
protected static Type[] types;

protected static Mock<IAssemblies> assemblies_mock;
protected static Mock<ITypeFinder> type_finder_mock;

Establish context = () =>
{
var assembliesMock = new Mock<IAssemblies>();
assembliesMock.Setup(x => x.GetAll()).Returns(new[]
{typeof (a_type_discoverer).Assembly});
TypeDiscoverer = new TypeDiscoverer(assembliesMock.Object);
types = new[] {
typeof(ISingle),
typeof(Single),
typeof(IMultiple),
typeof(FirstMultiple),
typeof(SecondMultiple)
};

assembly_mock = new Mock<_Assembly>();
assembly_mock.Setup(a => a.GetTypes()).Returns(types);
assembly_mock.Setup(a => a.FullName).Returns("A.Full.Name");

assemblies_mock = new Mock<IAssemblies>();
assemblies_mock.Setup(x => x.GetAll()).Returns(new[] { assembly_mock.Object });

type_finder_mock = new Mock<ITypeFinder>();
type_discoverer = new TypeDiscoverer(assemblies_mock.Object, type_finder_mock.Object);
};
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Bifrost.Execution;
using Machine.Specifications;

Expand All @@ -7,9 +8,12 @@ namespace Bifrost.Specs.Execution.for_TypeDiscoverer
[Subject(typeof(TypeDiscoverer))]
public class when_finding_type_by_name_that_does_not_exist : given.a_type_discoverer
{
static Type typeFound;
Because of = () => typeFound = TypeDiscoverer.FindTypeByFullName(typeof(Single).FullName + "Blah");
static Type type_found;

It should_be_null = () => typeFound.ShouldBeNull();
Establish context = () => type_finder_mock.Setup(t => t.FindTypeByFullName(Moq.It.IsAny<IEnumerable<Type>>(), Moq.It.IsAny<string>())).Returns((Type)null);

Because of = () => type_found = type_discoverer.FindTypeByFullName(typeof(Single).FullName + "Blah");

It should_be_null = () => type_found.ShouldBeNull();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Bifrost.Specs.Execution.for_TypeDiscoverer
public class when_finding_type_by_name_that_exists : given.a_type_discoverer
{
static Type typeFound;
Because of = () => typeFound = TypeDiscoverer.FindTypeByFullName(typeof(Single).FullName);
Because of = () => typeFound = type_discoverer.FindTypeByFullName(typeof(Single).FullName);

It should_not_return_null = () => typeFound.ShouldNotBeNull();
It should_return_the_correct_type = () => typeFound.ShouldEqual(typeof(Single));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Bifrost.Execution;
using Machine.Specifications;

Expand All @@ -7,11 +8,13 @@ namespace Bifrost.Specs.Execution.for_TypeDiscoverer
[Subject(typeof(TypeDiscoverer))]
public class when_finding_types_with_multiple_implementations : given.a_type_discoverer
{
static Type[] typesFound;
Because we_find_multiple = () => typesFound = TypeDiscoverer.FindMultiple<IMultiple>();
static IEnumerable<Type> types_found;

It should_not_return_null = () => typesFound.ShouldNotBeNull();
It should_return_2_types = () => typesFound.Length.ShouldEqual(2);
It should_contain_the_expected_types = () => typesFound.ShouldContain(typeof (FirstMultiple), typeof (SecondMultiple));
Establish context = () => type_finder_mock.Setup(t => t.FindMultiple<IMultiple>(Moq.It.IsAny<IEnumerable<Type>>())).Returns(new[] { typeof(FirstMultiple), typeof(SecondMultiple) });

Because of = () => types_found = type_discoverer.FindMultiple<IMultiple>();

It should_not_return_null = () => types_found.ShouldNotBeNull();
It should_contain_the_types_found_by_the_finder = () => types_found.ShouldContain(typeof (FirstMultiple), typeof (SecondMultiple));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Bifrost.Execution;
using Machine.Specifications;

Expand All @@ -8,7 +9,10 @@ namespace Bifrost.Specs.Execution.for_TypeDiscoverer
public class when_finding_types_with_only_one_implementation : given.a_type_discoverer
{
static Type typeFound;
Because we_find_single = () => typeFound = TypeDiscoverer.FindSingle<ISingle>();

Establish context = () => type_finder_mock.Setup(t => t.FindSingle<ISingle>(Moq.It.IsAny<IEnumerable<Type>>())).Returns(typeof(Single));

Because we_find_single = () => typeFound = type_discoverer.FindSingle<ISingle>();

It should_not_return_null = () => typeFound.ShouldNotBeNull();
It should_return_correct_implementation_when = () => typeFound.ShouldEqual(typeof (Single));
Expand Down
27 changes: 27 additions & 0 deletions Source/Bifrost.Specs/Execution/for_TypeFinder/Stubs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Bifrost.Specs.Execution.for_TypeFinder
{
public interface ISingle
{

}

public class Single : ISingle
{

}

public interface IMultiple
{

}

public class FirstMultiple : IMultiple
{

}

public class SecondMultiple : IMultiple
{

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using Bifrost.Execution;
using Machine.Specifications;

namespace Bifrost.Specs.Execution.for_TypeFinder.given
{
public class a_type_finder
{
protected static TypeFinder type_finder;
protected static IEnumerable<Type> types;

Establish context = () =>
{
types = new[] {
typeof(ISingle),
typeof(Single),
typeof(IMultiple),
typeof(FirstMultiple),
typeof(SecondMultiple)
};
type_finder = new TypeFinder();
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using Bifrost.Execution;
using Machine.Specifications;

namespace Bifrost.Specs.Execution.for_TypeFinder
{
[Subject(typeof(TypeFinder))]
public class when_finding_type_by_name_that_does_not_exist : given.a_type_finder
{
static Exception exception;

Because of = () => exception = Catch.Exception(() => type_finder.FindTypeByFullName(types, typeof(Single).FullName + "Blah"));

It should_be_throw_unable_to_resolve_type_by_name = () => exception.ShouldBeOfExactType<UnableToResolveTypeByName>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using Bifrost.Execution;
using Machine.Specifications;

namespace Bifrost.Specs.Execution.for_TypeFinder
{
[Subject(typeof(TypeFinder))]
public class when_finding_type_by_name_that_exists : given.a_type_finder
{
static Type type_found;

Because of = () => type_found = type_finder.FindTypeByFullName(types, typeof(Single).FullName);

It should_not_return_null = () => type_found.ShouldNotBeNull();
It should_return_the_correct_type = () => type_found.ShouldEqual(typeof(Single));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Bifrost.Execution;
using Machine.Specifications;

namespace Bifrost.Specs.Execution.for_TypeFinder
{
[Subject(typeof(TypeFinder))]
public class when_finding_types_with_multiple_implementations : given.a_type_finder
{
static IEnumerable<Type> types_found;

Because of = () => types_found = type_finder.FindMultiple<IMultiple>(types);

It should_not_return_null = () => types_found.ShouldNotBeNull();
It should_contain_the_expected_types = () => types_found.ShouldContain(typeof (FirstMultiple), typeof (SecondMultiple));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using Bifrost.Execution;
using Machine.Specifications;

namespace Bifrost.Specs.Execution.for_TypeFinder
{
[Subject(typeof(TypeFinder))]
public class when_finding_types_with_multiple_implementations_but_asking_for_a_single : given.a_type_finder
{
static Exception exception;

Because of = () => exception = Catch.Exception(() => type_finder.FindSingle<IMultiple>(types));

It should_throw_an_ArgumentException = () => exception.ShouldBeOfExactType<MultipleTypesFoundException>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using Bifrost.Execution;
using Machine.Specifications;

namespace Bifrost.Specs.Execution.for_TypeFinder
{
[Subject(typeof(TypeFinder))]
public class when_finding_types_with_only_one_implementation : given.a_type_finder
{
static Type type_found;

Because of = () => type_found = type_finder.FindSingle<ISingle>(types);

It should_not_return_null = () => type_found.ShouldNotBeNull();
It should_return_correct_implementation_when = () => type_found.ShouldEqual(typeof (Single));
}
}
3 changes: 2 additions & 1 deletion Source/Bifrost.Web/Services/JsonInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Collections.Generic;

namespace Bifrost.Web.Services
{
[Singleton]
public class JsonInterceptor : IJsonInterceptor
{
private readonly Type[] _valueInterceptors;
private readonly IEnumerable<Type> _valueInterceptors;
private readonly IContainer _container;

public JsonInterceptor(ITypeDiscoverer typeDiscoverer, IContainer container)
Expand Down
4 changes: 3 additions & 1 deletion Source/Bifrost/Bifrost.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,14 @@
<Compile Include="Execution\FileSystem.cs" />
<Compile Include="Execution\IAssemblyProvider.cs" />
<Compile Include="Execution\IAssemblyUtility.cs" />
<Compile Include="Execution\ICanFilterAssembly.cs" />
<Compile Include="Execution\ICanSpecifyAssemblies.cs" />
<Compile Include="Execution\IAssemblyFilters.cs" />
<Compile Include="Execution\IExecutionEnvironment.cs" />
<Compile Include="Execution\IFileSystem.cs" />
<Compile Include="Execution\InvalidSignatureException.cs" />
<Compile Include="Execution\CannotInvokeMethodBecauseTargetIsNotAlive.cs" />
<Compile Include="Execution\ITypeFinder.cs" />
<Compile Include="Execution\TypeFinder.cs" />
<Compile Include="Execution\WeakDelegate.cs" />
<Compile Include="Mapping\SourcePropertyMappingStrategy.cs" />
<Compile Include="MissingDefaultConstructorException.cs" />
Expand Down
1 change: 1 addition & 0 deletions Source/Bifrost/Configuration/Defaults/DefaultBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public void Initialize(IContainer container)
container.Bind<IAssemblyProvider>(_assemblyProvider);
container.Bind<IAssemblies>(typeof(global::Bifrost.Execution.Assemblies), BindingLifecycle.Singleton);
container.Bind<ITypeDiscoverer>(typeof(TypeDiscoverer), BindingLifecycle.Singleton);
container.Bind<ITypeFinder>(typeof(TypeFinder), BindingLifecycle.Singleton);
}
#pragma warning restore 1591 // Xml Comments
}
Expand Down
5 changes: 3 additions & 2 deletions Source/Bifrost/Execution/ExecutionContextDetailsPopulator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
// limitations under the License.
//
#endregion

using System;
using System.Collections.Generic;

namespace Bifrost.Execution
{
/// <summary>
Expand All @@ -27,7 +28,7 @@ public class ExecutionContextDetailsPopulator : IExecutionContextDetailsPopulato
{
ITypeDiscoverer _typeDiscoverer;
IContainer _container;
Type[] _populatorTypes;
IEnumerable<Type> _populatorTypes;

/// <summary>
/// Initializes an instance of <see cref="ExecutionContextDetailsPopulator"/>
Expand Down
Loading

0 comments on commit 3e787da

Please sign in to comment.