summaryrefslogtreecommitdiff
path: root/src/Notepad/Infrastructure/Container
diff options
context:
space:
mode:
Diffstat (limited to 'src/Notepad/Infrastructure/Container')
-rw-r--r--src/Notepad/Infrastructure/Container/DependencyResolutionException.cs9
-rw-r--r--src/Notepad/Infrastructure/Container/IDependencyRegistry.cs8
-rw-r--r--src/Notepad/Infrastructure/Container/Resolve.cs20
-rw-r--r--src/Notepad/Infrastructure/Container/ResolveSpecs.cs83
-rw-r--r--src/Notepad/Infrastructure/Container/Windsor/IComponentExclusionSpecification.cs15
-rw-r--r--src/Notepad/Infrastructure/Container/Windsor/IWindsorContainerFactory.cs42
-rw-r--r--src/Notepad/Infrastructure/Container/Windsor/WindsorDependencyRegistry.cs40
-rw-r--r--src/Notepad/Infrastructure/Container/Windsor/WindsorDependencyResolverSpecs.cs73
8 files changed, 290 insertions, 0 deletions
diff --git a/src/Notepad/Infrastructure/Container/DependencyResolutionException.cs b/src/Notepad/Infrastructure/Container/DependencyResolutionException.cs
new file mode 100644
index 0000000..fe36112
--- /dev/null
+++ b/src/Notepad/Infrastructure/Container/DependencyResolutionException.cs
@@ -0,0 +1,9 @@
+using System;
+using Notepad.Infrastructure.Extensions;
+
+namespace Notepad.Infrastructure.Container {
+ public class DependencyResolutionException<T> : Exception {
+ public DependencyResolutionException(Exception innerException)
+ : base("Could not resolve {0}".FormatWith(typeof (T).FullName), innerException) {}
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Container/IDependencyRegistry.cs b/src/Notepad/Infrastructure/Container/IDependencyRegistry.cs
new file mode 100644
index 0000000..fbcd911
--- /dev/null
+++ b/src/Notepad/Infrastructure/Container/IDependencyRegistry.cs
@@ -0,0 +1,8 @@
+using System.Collections.Generic;
+
+namespace Notepad.Infrastructure.Container {
+ public interface IDependencyRegistry {
+ Interface FindAnImplementationOf<Interface>();
+ IEnumerable<Interface> AllImplementationsOf<Interface>();
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Container/Resolve.cs b/src/Notepad/Infrastructure/Container/Resolve.cs
new file mode 100644
index 0000000..507ccb4
--- /dev/null
+++ b/src/Notepad/Infrastructure/Container/Resolve.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Notepad.Infrastructure.Container {
+ public static class Resolve {
+ private static IDependencyRegistry underlyingRegistry;
+
+ public static void InitializeWith(IDependencyRegistry registry) {
+ underlyingRegistry = registry;
+ }
+
+ public static DependencyToResolve DependencyFor<DependencyToResolve>() {
+ try {
+ return underlyingRegistry.FindAnImplementationOf<DependencyToResolve>();
+ }
+ catch (Exception e) {
+ throw new DependencyResolutionException<DependencyToResolve>(e);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Container/ResolveSpecs.cs b/src/Notepad/Infrastructure/Container/ResolveSpecs.cs
new file mode 100644
index 0000000..e16d137
--- /dev/null
+++ b/src/Notepad/Infrastructure/Container/ResolveSpecs.cs
@@ -0,0 +1,83 @@
+using System;
+using MbUnit.Framework;
+using Notepad.Presentation.Core;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Infrastructure.Container {
+ public class ResolveSpecs {}
+
+ [TestFixture]
+ public class when_resolving_a_dependency_using_the_resolve_gateway_ {
+ private MockRepository mockery;
+ private IDependencyRegistry registry;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ registry = mockery.DynamicMock<IDependencyRegistry>();
+ Resolve.InitializeWith(registry);
+ }
+
+ [Test]
+ public void should_leverage_the_underlying_container_it_was_initialized_with() {
+ var presenter = mockery.DynamicMock<IPresenter>();
+
+ using (mockery.Record()) {
+ Expect
+ .Call(registry.FindAnImplementationOf<IPresenter>())
+ .Return(presenter)
+ .Repeat
+ .AtLeastOnce();
+ }
+
+ using (mockery.Playback()) {
+ Resolve.DependencyFor<IPresenter>();
+ }
+ }
+
+ [Test]
+ public void should_return_the_resolved_dependency() {
+ var presenter = mockery.DynamicMock<IPresenter>();
+
+ using (mockery.Record()) {
+ Expect
+ .Call(registry.FindAnImplementationOf<IPresenter>())
+ .Return(presenter)
+ .Repeat
+ .AtLeastOnce();
+ }
+
+ using (mockery.Playback()) {
+ Resolve.DependencyFor<IPresenter>().ShouldBeEqualTo(presenter);
+ }
+ }
+ }
+
+ [TestFixture]
+ public class when_resolving_a_dependency_that_is_not_registered_ {
+ private MockRepository mockery;
+ private IDependencyRegistry registry;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ registry = mockery.DynamicMock<IDependencyRegistry>();
+ Resolve.InitializeWith(registry);
+ }
+
+ [Test]
+ [ExpectedException(typeof (DependencyResolutionException<IPresenter>))]
+ public void should_throw_a_dependency_resolution_exception() {
+ using (mockery.Record()) {
+ SetupResult
+ .For(registry.FindAnImplementationOf<IPresenter>())
+ .Throw(new Exception());
+ }
+
+ using (mockery.Playback()) {
+ Resolve.DependencyFor<IPresenter>();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Container/Windsor/IComponentExclusionSpecification.cs b/src/Notepad/Infrastructure/Container/Windsor/IComponentExclusionSpecification.cs
new file mode 100644
index 0000000..b611859
--- /dev/null
+++ b/src/Notepad/Infrastructure/Container/Windsor/IComponentExclusionSpecification.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Windows.Forms;
+using Notepad.Infrastructure.Core;
+
+namespace Notepad.Infrastructure.Container.Windsor {
+ public interface IComponentExclusionSpecification : ISpecification<Type> {}
+
+ public class ComponentExclusionSpecification : IComponentExclusionSpecification {
+ public bool IsSatisfiedBy(Type type) {
+ return type.GetInterfaces().Length == 0
+ || type.IsSubclassOf(typeof (Form))
+ || type.IsAssignableFrom(typeof (IDependencyRegistry));
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Container/Windsor/IWindsorContainerFactory.cs b/src/Notepad/Infrastructure/Container/Windsor/IWindsorContainerFactory.cs
new file mode 100644
index 0000000..4087a5e
--- /dev/null
+++ b/src/Notepad/Infrastructure/Container/Windsor/IWindsorContainerFactory.cs
@@ -0,0 +1,42 @@
+using Castle.MicroKernel.Registration;
+using Castle.Windsor;
+using Notepad.Infrastructure.Extensions;
+
+namespace Notepad.Infrastructure.Container.Windsor {
+ public interface IWindsorContainerFactory {
+ IWindsorContainer Create();
+ }
+
+ public class WindsorContainerFactory : IWindsorContainerFactory {
+ private static IWindsorContainer container;
+ private IComponentExclusionSpecification criteriaToSatisfy;
+
+ public WindsorContainerFactory() : this(new ComponentExclusionSpecification()) {}
+
+ public WindsorContainerFactory(IComponentExclusionSpecification criteriaToSatisfy) {
+ this.criteriaToSatisfy = criteriaToSatisfy;
+ }
+
+ public IWindsorContainer Create() {
+ if (null == container) {
+ container = new WindsorContainer();
+ container.Register(
+ AllTypes
+ .Pick()
+ .FromAssembly(GetType().Assembly)
+ .WithService
+ .FirstInterface()
+ .Unless(criteriaToSatisfy.IsSatisfiedBy)
+ .Configure(
+ delegate(ComponentRegistration registration) {
+ this.LogInformational("{1}-{0}", registration.Implementation, registration.ServiceType.Name);
+ if (registration.Implementation.GetInterfaces().Length == 0) {
+ registration.For(registration.Implementation);
+ }
+ })
+ );
+ }
+ return container;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Container/Windsor/WindsorDependencyRegistry.cs b/src/Notepad/Infrastructure/Container/Windsor/WindsorDependencyRegistry.cs
new file mode 100644
index 0000000..75cc206
--- /dev/null
+++ b/src/Notepad/Infrastructure/Container/Windsor/WindsorDependencyRegistry.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using Castle.Windsor;
+using Notepad.Infrastructure.Extensions;
+
+namespace Notepad.Infrastructure.Container.Windsor {
+ public class WindsorDependencyRegistry : IDependencyRegistry {
+ private IWindsorContainer underlyingContainer;
+
+ public WindsorDependencyRegistry() : this(new WindsorContainerFactory()) {}
+
+ public WindsorDependencyRegistry(IWindsorContainerFactory factory) {
+ underlyingContainer = factory.Create();
+ }
+
+ public Interface FindAnImplementationOf<Interface>() {
+ return underlyingContainer.Kernel.Resolve<Interface>();
+ }
+
+ public void Register(Type typeOfInterface, Type typeOfImplementation) {
+ underlyingContainer
+ .Kernel
+ .AddComponent("{0}-{1}".FormatWith(typeOfInterface.FullName, typeOfImplementation.FullName),
+ typeOfInterface,
+ typeOfImplementation);
+ }
+
+ public void Register<Interface, Implementation>() {
+ Register(typeof (Interface), typeof (Implementation));
+ }
+
+ public void RegisterInstanceOf<Interface>(Interface instanceOfTheInterface) {
+ underlyingContainer.Kernel.AddComponentInstance<Interface>(instanceOfTheInterface);
+ }
+
+ public IEnumerable<Interface> AllImplementationsOf<Interface>() {
+ return underlyingContainer.Kernel.ResolveAll<Interface>();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Container/Windsor/WindsorDependencyResolverSpecs.cs b/src/Notepad/Infrastructure/Container/Windsor/WindsorDependencyResolverSpecs.cs
new file mode 100644
index 0000000..8235643
--- /dev/null
+++ b/src/Notepad/Infrastructure/Container/Windsor/WindsorDependencyResolverSpecs.cs
@@ -0,0 +1,73 @@
+using Castle.Windsor;
+using MbUnit.Framework;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Infrastructure.Container.Windsor {
+ public class WindsorDependencyResolverSpecs {}
+
+
+ [TestFixture]
+ public class when_registering_a_singleton_component_with_the_windsor_container_ {
+ private WindsorDependencyRegistry sut;
+
+ [SetUp]
+ public void SetUp() {
+ sut = CreateSUT();
+ }
+
+ [Test]
+ public void should_return_the_same_instance_each_time_its_resolved() {
+ sut
+ .FindAnImplementationOf<IBird>()
+ .ShouldBeSameInstanceAs(sut.FindAnImplementationOf<IBird>());
+ }
+
+ [Test]
+ public void should_not_return_null() {
+ sut.FindAnImplementationOf<IBird>().ShouldNotBeNull();
+ }
+
+ private WindsorDependencyRegistry CreateSUT() {
+ return new WindsorDependencyRegistry();
+ }
+ }
+
+ [TestFixture]
+ public class when_creating_the_windsor_resolver_ {
+ private MockRepository mockery;
+ private IWindsorContainerFactory factory;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ factory = mockery.DynamicMock<IWindsorContainerFactory>();
+ }
+
+ [Test]
+ public void should_leverage_the_factory_to_create_the_underlying_container() {
+ var container = new WindsorContainer();
+ using (mockery.Record()) {
+ Expect
+ .Call(factory.Create())
+ .Return(container)
+ .Repeat
+ .AtLeastOnce();
+ }
+
+ using (mockery.Playback()) {
+ CreateSUT();
+ }
+ }
+
+ private IDependencyRegistry CreateSUT() {
+ return new WindsorDependencyRegistry(factory);
+ }
+ }
+
+ public class BlueBird : IBird {
+ public void Initialize() {}
+ }
+
+ public interface IBird {}
+} \ No newline at end of file