diff --git a/Source/Bifrost.Silverlight/Bifrost.Silverlight.csproj b/Source/Bifrost.Silverlight/Bifrost.Silverlight.csproj
index 699fb0d66..c7ba63d9d 100644
--- a/Source/Bifrost.Silverlight/Bifrost.Silverlight.csproj
+++ b/Source/Bifrost.Silverlight/Bifrost.Silverlight.csproj
@@ -626,6 +626,9 @@
Execution\ITypeDiscoverer.cs
+
+ Execution\ITypeFinder.cs
+
Execution\ITypeImporter.cs
@@ -644,6 +647,9 @@
Execution\TypeDiscoverer.cs
+
+ Execution\TypeFinder.cs
+
Execution\TypeImporter.cs
diff --git a/Source/Bifrost.Specs/Bifrost.Specs.csproj b/Source/Bifrost.Specs/Bifrost.Specs.csproj
index 982d86bd6..ee3b4e6a2 100644
--- a/Source/Bifrost.Specs/Bifrost.Specs.csproj
+++ b/Source/Bifrost.Specs/Bifrost.Specs.csproj
@@ -331,6 +331,13 @@
+
+
+
+
+
+
+
@@ -722,7 +729,6 @@
-
diff --git a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/given/a_type_discoverer.cs b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/given/a_type_discoverer.cs
index cb15b9bd8..001cad33f 100644
--- a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/given/a_type_discoverer.cs
+++ b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/given/a_type_discoverer.cs
@@ -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;
@@ -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 assemblies_mock;
+ protected static Mock type_finder_mock;
Establish context = () =>
{
- var assembliesMock = new Mock();
- 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();
+ assemblies_mock.Setup(x => x.GetAll()).Returns(new[] { assembly_mock.Object });
+
+ type_finder_mock = new Mock();
+ type_discoverer = new TypeDiscoverer(assemblies_mock.Object, type_finder_mock.Object);
};
}
}
diff --git a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_type_by_name_that_does_not_exist.cs b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_type_by_name_that_does_not_exist.cs
index 7624f9af2..8dac029ee 100644
--- a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_type_by_name_that_does_not_exist.cs
+++ b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_type_by_name_that_does_not_exist.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Bifrost.Execution;
using Machine.Specifications;
@@ -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>(), Moq.It.IsAny())).Returns((Type)null);
+
+ Because of = () => type_found = type_discoverer.FindTypeByFullName(typeof(Single).FullName + "Blah");
+
+ It should_be_null = () => type_found.ShouldBeNull();
}
}
\ No newline at end of file
diff --git a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_type_by_name_that_exists.cs b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_type_by_name_that_exists.cs
index 947ce47dd..a94fefaaa 100644
--- a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_type_by_name_that_exists.cs
+++ b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_type_by_name_that_exists.cs
@@ -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));
diff --git a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_multiple_implementations.cs b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_multiple_implementations.cs
index dc21d463b..fb7ea6a7d 100644
--- a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_multiple_implementations.cs
+++ b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_multiple_implementations.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Bifrost.Execution;
using Machine.Specifications;
@@ -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();
+ static IEnumerable 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(Moq.It.IsAny>())).Returns(new[] { typeof(FirstMultiple), typeof(SecondMultiple) });
+
+ Because of = () => types_found = type_discoverer.FindMultiple();
+
+ It should_not_return_null = () => types_found.ShouldNotBeNull();
+ It should_contain_the_types_found_by_the_finder = () => types_found.ShouldContain(typeof (FirstMultiple), typeof (SecondMultiple));
}
}
\ No newline at end of file
diff --git a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_multiple_implementations_but_asking_for_a_single.cs b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_multiple_implementations_but_asking_for_a_single.cs
deleted file mode 100644
index 68f48ccde..000000000
--- a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_multiple_implementations_but_asking_for_a_single.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using Bifrost.Execution;
-using Machine.Specifications;
-
-namespace Bifrost.Specs.Execution.for_TypeDiscoverer
-{
- [Subject(typeof(TypeDiscoverer))]
- public class when_finding_types_with_multiple_implementations_but_asking_for_a_single : given.a_type_discoverer
- {
- static Exception Exception;
- Because we_ask_for_a_single = () => Exception = Catch.Exception(() => TypeDiscoverer.FindSingle());
-
- It should_throw_an_ArgumentException = () => Exception.ShouldBeOfExactType();
- }
-}
\ No newline at end of file
diff --git a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_only_one_implementation.cs b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_only_one_implementation.cs
index 3e294213a..f7d87e64d 100644
--- a/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_only_one_implementation.cs
+++ b/Source/Bifrost.Specs/Execution/for_TypeDiscoverer/when_finding_types_with_only_one_implementation.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Bifrost.Execution;
using Machine.Specifications;
@@ -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();
+
+ Establish context = () => type_finder_mock.Setup(t => t.FindSingle(Moq.It.IsAny>())).Returns(typeof(Single));
+
+ Because we_find_single = () => typeFound = type_discoverer.FindSingle();
It should_not_return_null = () => typeFound.ShouldNotBeNull();
It should_return_correct_implementation_when = () => typeFound.ShouldEqual(typeof (Single));
diff --git a/Source/Bifrost.Specs/Execution/for_TypeFinder/Stubs.cs b/Source/Bifrost.Specs/Execution/for_TypeFinder/Stubs.cs
new file mode 100644
index 000000000..7dbac15f4
--- /dev/null
+++ b/Source/Bifrost.Specs/Execution/for_TypeFinder/Stubs.cs
@@ -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
+ {
+
+ }
+}
diff --git a/Source/Bifrost.Specs/Execution/for_TypeFinder/given/a_type_finder.cs b/Source/Bifrost.Specs/Execution/for_TypeFinder/given/a_type_finder.cs
new file mode 100644
index 000000000..7b7a100c7
--- /dev/null
+++ b/Source/Bifrost.Specs/Execution/for_TypeFinder/given/a_type_finder.cs
@@ -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 types;
+
+ Establish context = () =>
+ {
+ types = new[] {
+ typeof(ISingle),
+ typeof(Single),
+ typeof(IMultiple),
+ typeof(FirstMultiple),
+ typeof(SecondMultiple)
+ };
+ type_finder = new TypeFinder();
+ };
+ }
+}
diff --git a/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_type_by_name_that_does_not_exist.cs b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_type_by_name_that_does_not_exist.cs
new file mode 100644
index 000000000..3ec64ffd6
--- /dev/null
+++ b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_type_by_name_that_does_not_exist.cs
@@ -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();
+ }
+}
\ No newline at end of file
diff --git a/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_type_by_name_that_exists.cs b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_type_by_name_that_exists.cs
new file mode 100644
index 000000000..ab9a0620f
--- /dev/null
+++ b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_type_by_name_that_exists.cs
@@ -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));
+ }
+}
\ No newline at end of file
diff --git a/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_multiple_implementations.cs b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_multiple_implementations.cs
new file mode 100644
index 000000000..5e65707dc
--- /dev/null
+++ b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_multiple_implementations.cs
@@ -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 types_found;
+
+ Because of = () => types_found = type_finder.FindMultiple(types);
+
+ It should_not_return_null = () => types_found.ShouldNotBeNull();
+ It should_contain_the_expected_types = () => types_found.ShouldContain(typeof (FirstMultiple), typeof (SecondMultiple));
+ }
+}
\ No newline at end of file
diff --git a/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_multiple_implementations_but_asking_for_a_single.cs b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_multiple_implementations_but_asking_for_a_single.cs
new file mode 100644
index 000000000..75928a8b8
--- /dev/null
+++ b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_multiple_implementations_but_asking_for_a_single.cs
@@ -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(types));
+
+ It should_throw_an_ArgumentException = () => exception.ShouldBeOfExactType();
+ }
+}
\ No newline at end of file
diff --git a/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_only_one_implementation.cs b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_only_one_implementation.cs
new file mode 100644
index 000000000..6fa01f4c0
--- /dev/null
+++ b/Source/Bifrost.Specs/Execution/for_TypeFinder/when_finding_types_with_only_one_implementation.cs
@@ -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(types);
+
+ It should_not_return_null = () => type_found.ShouldNotBeNull();
+ It should_return_correct_implementation_when = () => type_found.ShouldEqual(typeof (Single));
+ }
+}
\ No newline at end of file
diff --git a/Source/Bifrost.Web/Services/JsonInterceptor.cs b/Source/Bifrost.Web/Services/JsonInterceptor.cs
index 1d92757e2..f4c183721 100644
--- a/Source/Bifrost.Web/Services/JsonInterceptor.cs
+++ b/Source/Bifrost.Web/Services/JsonInterceptor.cs
@@ -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 _valueInterceptors;
private readonly IContainer _container;
public JsonInterceptor(ITypeDiscoverer typeDiscoverer, IContainer container)
diff --git a/Source/Bifrost/Bifrost.csproj b/Source/Bifrost/Bifrost.csproj
index 6cc721ee5..ddfd14094 100644
--- a/Source/Bifrost/Bifrost.csproj
+++ b/Source/Bifrost/Bifrost.csproj
@@ -159,12 +159,14 @@
-
+
+
+
diff --git a/Source/Bifrost/Configuration/Defaults/DefaultBindings.cs b/Source/Bifrost/Configuration/Defaults/DefaultBindings.cs
index b5b699c27..183584bc0 100644
--- a/Source/Bifrost/Configuration/Defaults/DefaultBindings.cs
+++ b/Source/Bifrost/Configuration/Defaults/DefaultBindings.cs
@@ -51,6 +51,7 @@ public void Initialize(IContainer container)
container.Bind(_assemblyProvider);
container.Bind(typeof(global::Bifrost.Execution.Assemblies), BindingLifecycle.Singleton);
container.Bind(typeof(TypeDiscoverer), BindingLifecycle.Singleton);
+ container.Bind(typeof(TypeFinder), BindingLifecycle.Singleton);
}
#pragma warning restore 1591 // Xml Comments
}
diff --git a/Source/Bifrost/Execution/ExecutionContextDetailsPopulator.cs b/Source/Bifrost/Execution/ExecutionContextDetailsPopulator.cs
index 704d8de67..14d0428ab 100644
--- a/Source/Bifrost/Execution/ExecutionContextDetailsPopulator.cs
+++ b/Source/Bifrost/Execution/ExecutionContextDetailsPopulator.cs
@@ -16,8 +16,9 @@
// limitations under the License.
//
#endregion
-
using System;
+using System.Collections.Generic;
+
namespace Bifrost.Execution
{
///
@@ -27,7 +28,7 @@ public class ExecutionContextDetailsPopulator : IExecutionContextDetailsPopulato
{
ITypeDiscoverer _typeDiscoverer;
IContainer _container;
- Type[] _populatorTypes;
+ IEnumerable _populatorTypes;
///
/// Initializes an instance of
diff --git a/Source/Bifrost/Execution/ICanFilterAssembly.cs b/Source/Bifrost/Execution/ICanSpecifyAssemblies.cs
similarity index 68%
rename from Source/Bifrost/Execution/ICanFilterAssembly.cs
rename to Source/Bifrost/Execution/ICanSpecifyAssemblies.cs
index d5cc6b7d7..d1ae68f63 100644
--- a/Source/Bifrost/Execution/ICanFilterAssembly.cs
+++ b/Source/Bifrost/Execution/ICanSpecifyAssemblies.cs
@@ -16,13 +16,12 @@
// limitations under the License.
//
#endregion
-using System.Reflection;
-using System.Runtime.InteropServices;
+using Bifrost.Configuration.Assemblies;
namespace Bifrost.Execution
{
///
- /// Defines something that tell wether or not to filter away an assembly.
+ /// Specifies what assemblies to include
///
///
/// Typically used by implementations of to
@@ -30,14 +29,12 @@ namespace Bifrost.Execution
/// which relies on knowing about assemblies
/// to be able to discover types.
///
- public interface ICanFilterAssembly
+ public interface ICanSpecifyAssemblies
{
///
- /// Method that gets called participating in the chain to decide wether or
- /// not an assembly should be included
+ /// Method that gets called for specifying which assemblies to include or not
///
- /// to check
- /// True if it should be included, false if not
- bool ShouldInclude(_Assembly assembly);
+ /// object to specfiy on
+ void Specify(AssembliesConfiguration configuration);
}
}
diff --git a/Source/Bifrost/Execution/ITypeDiscoverer.cs b/Source/Bifrost/Execution/ITypeDiscoverer.cs
index 2b3d8f485..48ec63cde 100644
--- a/Source/Bifrost/Execution/ITypeDiscoverer.cs
+++ b/Source/Bifrost/Execution/ITypeDiscoverer.cs
@@ -53,7 +53,7 @@ public interface ITypeDiscoverer
/// If the base type is an interface, it will look for any types implementing the interface.
/// If it is a class, it will find anyone inheriting from that class
///
- Type[] FindMultiple();
+ IEnumerable FindMultiple();
///
/// Find a single implementation of a basetype
@@ -76,7 +76,7 @@ public interface ITypeDiscoverer
/// If the base type is an interface, it will look for any types implementing the interface.
/// If it is a class, it will find anyone inheriting from that class
///
- Type[] FindMultiple(Type type);
+ IEnumerable FindMultiple(Type type);
///
/// Find a single type using the full name, without assembly
diff --git a/Source/Bifrost/Execution/ITypeFinder.cs b/Source/Bifrost/Execution/ITypeFinder.cs
new file mode 100644
index 000000000..dbfafbdaf
--- /dev/null
+++ b/Source/Bifrost/Execution/ITypeFinder.cs
@@ -0,0 +1,87 @@
+#region License
+//
+// Copyright (c) 2008-2015, Dolittle (http://www.dolittle.com)
+//
+// Licensed under the MIT License (http://opensource.org/licenses/MIT)
+//
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the license at
+//
+// http://github.com/dolittle/Bifrost/blob/master/MIT-LICENSE.txt
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+using System;
+using System.Collections.Generic;
+
+namespace Bifrost.Execution
+{
+ ///
+ /// Defines a system that is capable of finding types based on base types
+ ///
+ public interface ITypeFinder
+ {
+ ///
+ /// Find a single implementation of a basetype
+ ///
+ /// Types to find from
+ /// Basetype to find for
+ /// Type found
+ ///
+ /// If the base type is an interface, it will look for any types implementing the interface.
+ /// If it is a class, it will find anyone inheriting from that class
+ ///
+ /// If there is more than one instance found
+ Type FindSingle(IEnumerable types);
+
+ ///
+ /// Find multiple implementations of a basetype
+ ///
+ /// Types to find from
+ /// Basetype to find for
+ /// All types implementing or inheriting from the given basetype
+ ///
+ /// If the base type is an interface, it will look for any types implementing the interface.
+ /// If it is a class, it will find anyone inheriting from that class
+ ///
+ IEnumerable FindMultiple(IEnumerable types);
+
+ ///
+ /// Find a single implementation of a basetype
+ ///
+ /// Types to find from
+ /// Basetype to find for
+ /// Type found
+ ///
+ /// If the base type is an interface, it will look for any types implementing the interface.
+ /// If it is a class, it will find anyone inheriting from that class
+ ///
+ /// If there is more than one instance found
+ Type FindSingle(IEnumerable types, Type type);
+
+ ///
+ /// Find multiple implementations of a basetype
+ ///
+ /// Types to find from
+ /// Basetype to find for
+ /// All types implementing or inheriting from the given basetype
+ ///
+ /// If the base type is an interface, it will look for any types implementing the interface.
+ /// If it is a class, it will find anyone inheriting from that class
+ ///
+ IEnumerable FindMultiple(IEnumerable types, Type type);
+
+ ///
+ /// Find a single type using the full name, without assembly
+ ///
+ /// Types to find from
+ /// full name of the type to find
+ /// The type is found, null otherwise
+ Type FindTypeByFullName(IEnumerable types, string fullName);
+ }
+}
diff --git a/Source/Bifrost/Execution/TypeDiscoverer.cs b/Source/Bifrost/Execution/TypeDiscoverer.cs
index bb6dbde19..511d33533 100644
--- a/Source/Bifrost/Execution/TypeDiscoverer.cs
+++ b/Source/Bifrost/Execution/TypeDiscoverer.cs
@@ -42,15 +42,14 @@ public class TypeDiscoverer : ITypeDiscoverer
static List NamespaceStartingWithExclusions = new List();
IAssemblies _assemblies;
+ ITypeFinder _typeFinder;
#if(SILVERLIGHT || WINDOWS_PHONE)
- Dictionary> _types;
+ List _types;
#else
- ConcurrentDictionary> _types;
+ ConcurrentBag _types;
#endif
- IDictionary _implementingTypes;
-
///
/// Exclude discovering of types in a specific namespace
///
@@ -63,17 +62,18 @@ public static void ExcludeNamespaceStartingWith(string name)
///
/// Initializes a new instance of TypeDiscoverer
///
- public TypeDiscoverer(IAssemblies assemblies)
+ /// for getting assemblies
+ /// for finding types from all collected types
+ public TypeDiscoverer(IAssemblies assemblies, ITypeFinder typeFinder)
{
_assemblies = assemblies;
+ _typeFinder = typeFinder;
#if(SILVERLIGHT)
- _types = new Dictionary>();
+ _types = new List();
#else
- _types = new ConcurrentDictionary>();
+ _types = new ConcurrentBag();
#endif
-
- _implementingTypes = new Dictionary();
CollectTypes();
}
@@ -81,90 +81,41 @@ public TypeDiscoverer(IAssemblies assemblies)
#pragma warning disable 1591 // Xml Comments
public IEnumerable GetAll()
{
- return _types.Values.SelectMany(x => x.Values.ToList());
+ return _types;
}
public Type FindSingle()
{
- var type = FindSingle(typeof(T));
- return type;
+ return _typeFinder.FindSingle(_types);
}
- public Type[] FindMultiple()
+ public IEnumerable FindMultiple()
{
- var types = FindMultiple(typeof(T));
- return types;
+ return _typeFinder.FindMultiple(_types);
}
public Type FindSingle(Type type)
{
- var typesFound = Find(type);
-
- if (typesFound.Length > 1)
- throw new MultipleTypesFoundException(string.Format("More than one type found for '{0}'", type.FullName));
- return typesFound.SingleOrDefault();
+ return _typeFinder.FindSingle(_types, type);
}
- public Type[] FindMultiple(Type type)
+ public IEnumerable FindMultiple(Type type)
{
- var typesFound = Find(type);
- return typesFound;
+ return _typeFinder.FindMultiple(_types, type);
}
public Type FindTypeByFullName(string fullName)
{
- if (!_types.ContainsKey(fullName)) return null;
-
- var match = _types[fullName].Values;
-
- if (match.Count > 1)
- {
- throw new UnableToResolveTypeByName(fullName);
- }
-
- return match.First();
+ return _typeFinder.FindTypeByFullName(_types, fullName);
}
#pragma warning restore 1591 // Xml Comments
-#if(SILVERLIGHT || WINDOWS_PHONE)
-
- void AddTypes(IEnumerable types)
- {
- foreach (var type in types)
- {
- if (_types.ContainsKey(type.FullName))
- {
- var entry = _types[type.Assembly.FullName];
- entry[type.Assembly.FullName] = type;
- }
- else
- {
- _types.Add(type.FullName, new Dictionary {{type.Assembly.FullName, type}});
- }
- }
- }
-
-#else
-
void AddTypes(IEnumerable types)
{
- foreach (var type in types)
- {
- if (!_types.TryAdd(type.FullName, new Dictionary { { type.Assembly.FullName, type } }))
- {
- var entry = _types[type.FullName];
-
- lock (entry)
- {
- entry[type.Assembly.FullName] = type;
- }
- }
-
- }
+ types.ForEach(_types.Add);
}
-#endif
#if(WINDOWS_PHONE)
void CollectTypes()
@@ -245,32 +196,5 @@ static bool NameStartsWithAnExcludedNamespace(string name)
{
return NamespaceStartingWithExclusions.Any(name.StartsWith);
}
-
- Type[] Find(Type type)
- {
- Type[] typesFound;
-
- Func isAssignableFrom = (t1, t2) => t2.IsAssignableFrom(t1);
- if (type.IsInterface) isAssignableFrom = (t1, t2) => t1.HasInterface(t2);
-
- if (!_implementingTypes.TryGetValue(type, out typesFound))
- {
- var query = from t in _types.Values.SelectMany(a => a.Values)
- where
- isAssignableFrom(t,type) &&
-#if(NETFX_CORE)
- !t.GetTypeInfo().IsInterface &&
- !t.GetTypeInfo().IsAbstract
-#else
- !t.IsInterface &&
- !t.IsAbstract
-#endif
- select t;
- typesFound = query.ToArray();
- _implementingTypes[type] = typesFound;
- }
-
- return typesFound;
- }
}
}
diff --git a/Source/Bifrost/Execution/TypeFinder.cs b/Source/Bifrost/Execution/TypeFinder.cs
new file mode 100644
index 000000000..418a702ad
--- /dev/null
+++ b/Source/Bifrost/Execution/TypeFinder.cs
@@ -0,0 +1,99 @@
+#region License
+//
+// Copyright (c) 2008-2015, Dolittle (http://www.dolittle.com)
+//
+// Licensed under the MIT License (http://opensource.org/licenses/MIT)
+//
+// You may not use this file except in compliance with the License.
+// You may obtain a copy of the license at
+//
+// http://github.com/dolittle/Bifrost/blob/master/MIT-LICENSE.txt
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Linq;
+#if(SILVERLIGHT)
+using System.Windows;
+#endif
+using Bifrost.Extensions;
+
+namespace Bifrost.Execution
+{
+ ///
+ /// Represents an implementation of
+ ///
+ public class TypeFinder : ITypeFinder
+ {
+#pragma warning disable 1591 // Xml Comments
+ public Type FindSingle(IEnumerable types)
+ {
+ var type = FindSingle(types, typeof(T));
+ return type;
+ }
+
+ public IEnumerable FindMultiple(IEnumerable types)
+ {
+ var typesFound = FindMultiple(types, typeof(T));
+ return typesFound;
+ }
+
+ public Type FindSingle(IEnumerable types, Type type)
+ {
+ var typesFound = Find(types, type);
+ ThrowIfMultipleTypesFound(type, typesFound);
+ return typesFound.SingleOrDefault();
+ }
+
+ public IEnumerable FindMultiple(IEnumerable types, Type type)
+ {
+ var typesFound = Find(types, type);
+ return typesFound;
+ }
+
+ public Type FindTypeByFullName(IEnumerable types, string fullName)
+ {
+ var typeFound = types.Where(t => t.FullName == fullName).SingleOrDefault();
+ ThrowIfTypeNotFound(fullName, typeFound);
+ return typeFound;
+ }
+#pragma warning restore 1591 // Xml Comments
+ Type[] Find(IEnumerable types, Type type)
+ {
+ Func isAssignableFrom = (t1, t2) => t2.IsAssignableFrom(t1);
+ if (type.IsInterface) isAssignableFrom = (t1, t2) => t1.HasInterface(t2);
+
+ var query = types.Where(
+ t=>isAssignableFrom(t,type) &&
+#if(NETFX_CORE)
+ !t.GetTypeInfo().IsInterface &&
+ !t.GetTypeInfo().IsAbstract
+
+#else
+ !t.IsInterface &&
+ !t.IsAbstract
+#endif
+ );
+
+ var typesFound = query.ToArray();
+ return typesFound;
+ }
+
+ void ThrowIfMultipleTypesFound(Type type, Type[] typesFound)
+ {
+ if (typesFound.Length > 1)
+ throw new MultipleTypesFoundException(string.Format("More than one type found for '{0}'", type.FullName));
+ }
+
+ void ThrowIfTypeNotFound(string fullName, Type typeFound)
+ {
+ if (typeFound == null) throw new UnableToResolveTypeByName(fullName);
+ }
+ }
+}
diff --git a/Source/Bifrost/Execution/TypeImporter.cs b/Source/Bifrost/Execution/TypeImporter.cs
index 54750a6a8..3021e960c 100644
--- a/Source/Bifrost/Execution/TypeImporter.cs
+++ b/Source/Bifrost/Execution/TypeImporter.cs
@@ -17,6 +17,8 @@
//
#endregion
using System;
+using System.Collections.Generic;
+using System.Linq;
namespace Bifrost.Execution
{
@@ -46,26 +48,19 @@ public T[] ImportMany()
try
{
var types = _typeDiscoverer.FindMultiple();
- if( types == null )
- {
- throw new ArgumentException(
- string.Format("Can't import type {0}, it was not discovered", typeof(T)));
- }
- var instances = new T[types.Length];
- for (var instanceIndex = 0; instanceIndex < types.Length; instanceIndex++)
- {
- instances[instanceIndex] = (T) _container.Get(types[instanceIndex]);
- }
-
+ ThrowIfTypeCanNotBeImported(typeof(T), types);
+ var instances = types.Select(t => (T)_container.Get(t)).ToArray();
return instances;
}
catch (ArgumentException innerException)
{
- throw new ArgumentException(
- string.Format("Can't import type {0}, see inner exception for details", typeof(T)), innerException);
+ ThrowUnableToImportType(typeof(T),innerException);
}
+ return new T[0];
}
+
+
public T Import()
{
try
@@ -78,16 +73,33 @@ public T Import()
}
else
{
- throw new ArgumentException(
- string.Format("Can't import type {0}, it was not discovered", typeof(T)));
+ ThrowCanNotBeImported(typeof(T));
}
}
catch (ArgumentException innerException)
{
- throw new ArgumentException(
- string.Format("Can't import type {0}, see inner exception for details", typeof(T)), innerException);
+ ThrowUnableToImportType(typeof(T), innerException);
}
+ return default(T);
}
#pragma warning restore 1591 // Xml Comments
+
+ void ThrowUnableToImportType(Type type, ArgumentException innerException)
+ {
+ throw new ArgumentException(
+ string.Format("Can't import type {0}, see inner exception for details", type), innerException);
+ }
+
+ void ThrowIfTypeCanNotBeImported(Type type, IEnumerable types)
+ {
+ if (types == null) ThrowCanNotBeImported(type);
+ }
+
+ void ThrowCanNotBeImported(Type type)
+ {
+ throw new ArgumentException(
+ string.Format("Can't import type {0}, it was not discovered", type));
+ }
+
}
}
\ No newline at end of file
diff --git a/Source/Bifrost/Execution/UnableToResolveTypeByName.cs b/Source/Bifrost/Execution/UnableToResolveTypeByName.cs
index 01d598ecb..edf819eab 100644
--- a/Source/Bifrost/Execution/UnableToResolveTypeByName.cs
+++ b/Source/Bifrost/Execution/UnableToResolveTypeByName.cs
@@ -29,7 +29,7 @@ public class UnableToResolveTypeByName : ArgumentException
/// Initializes an instance of
///
///
- public UnableToResolveTypeByName(string typeName) : base(string.Format("Unable to resolve '{0}'. More than one type found with the current name'", typeName))
+ public UnableToResolveTypeByName(string typeName) : base(string.Format("Unable to resolve '{0}'.", typeName))
{
}
diff --git a/Source/Bifrost/Read/ReadModelFilters.cs b/Source/Bifrost/Read/ReadModelFilters.cs
index 4bd9e2bd3..ff4faf502 100644
--- a/Source/Bifrost/Read/ReadModelFilters.cs
+++ b/Source/Bifrost/Read/ReadModelFilters.cs
@@ -18,6 +18,7 @@
#endregion
using System;
using System.Collections.Generic;
+using System.Linq;
using Bifrost.Execution;
namespace Bifrost.Read
@@ -28,7 +29,7 @@ namespace Bifrost.Read
public class ReadModelFilters : IReadModelFilters
{
IContainer _container;
- Type[] _filterTypes;
+ IEnumerable _filterTypes;
///
/// Initializes an instance of
@@ -45,7 +46,7 @@ public ReadModelFilters(ITypeDiscoverer typeDiscoverer, IContainer container)
#pragma warning disable 1591
public IEnumerable Filter(IEnumerable readModels)
{
- if (_filterTypes.Length == 0) return readModels;
+ if (_filterTypes.Count() == 0) return readModels;
foreach (var filterType in _filterTypes)
{