summaryrefslogtreecommitdiff
path: root/src/Notepad/Infrastructure
diff options
context:
space:
mode:
authormo <mo.khan@gmail.com>2018-11-04 15:22:16 -0700
committermo <mo.khan@gmail.com>2018-11-04 15:22:16 -0700
commit5ee1f55497a4e30322a56f133f897ecde1612967 (patch)
treebf544e0879234c3623869627d8786776cb19b8e9 /src/Notepad/Infrastructure
initial commit.HEADmaster
Diffstat (limited to 'src/Notepad/Infrastructure')
-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
-rw-r--r--src/Notepad/Infrastructure/Core/ICommand.cs5
-rw-r--r--src/Notepad/Infrastructure/Core/IMapper.cs5
-rw-r--r--src/Notepad/Infrastructure/Core/ISpecification.cs5
-rw-r--r--src/Notepad/Infrastructure/Extensions/ConversionExtensions.cs7
-rw-r--r--src/Notepad/Infrastructure/Extensions/EnumerableExtensions.cs24
-rw-r--r--src/Notepad/Infrastructure/Extensions/LoggingExtensions.cs17
-rw-r--r--src/Notepad/Infrastructure/Extensions/SpecificationExtensions.cs14
-rw-r--r--src/Notepad/Infrastructure/Extensions/StringExtensions.cs13
-rw-r--r--src/Notepad/Infrastructure/Logging/ILogFactory.cs7
-rw-r--r--src/Notepad/Infrastructure/Logging/ILogger.cs8
-rw-r--r--src/Notepad/Infrastructure/Logging/Log.cs15
-rw-r--r--src/Notepad/Infrastructure/Logging/Log4NetLogging/Log4NetLogFactory.cs20
-rw-r--r--src/Notepad/Infrastructure/Logging/Log4NetLogging/Log4NetLogger.cs20
-rw-r--r--src/Notepad/Infrastructure/Logging/LogSpecs.cs40
-rw-r--r--src/Notepad/Infrastructure/System/IApplicationEnvironment.cs13
23 files changed, 503 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
diff --git a/src/Notepad/Infrastructure/Core/ICommand.cs b/src/Notepad/Infrastructure/Core/ICommand.cs
new file mode 100644
index 0000000..1fadec3
--- /dev/null
+++ b/src/Notepad/Infrastructure/Core/ICommand.cs
@@ -0,0 +1,5 @@
+namespace Notepad.Infrastructure.Core {
+ public interface ICommand {
+ void Execute();
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Core/IMapper.cs b/src/Notepad/Infrastructure/Core/IMapper.cs
new file mode 100644
index 0000000..39bad69
--- /dev/null
+++ b/src/Notepad/Infrastructure/Core/IMapper.cs
@@ -0,0 +1,5 @@
+namespace Notepad.Infrastructure.Core {
+ public interface IMapper<Input, Output> {
+ Output MapFrom(Input item);
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Core/ISpecification.cs b/src/Notepad/Infrastructure/Core/ISpecification.cs
new file mode 100644
index 0000000..c61d8b9
--- /dev/null
+++ b/src/Notepad/Infrastructure/Core/ISpecification.cs
@@ -0,0 +1,5 @@
+namespace Notepad.Infrastructure.Core {
+ public interface ISpecification<T> {
+ bool IsSatisfiedBy(T item);
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Extensions/ConversionExtensions.cs b/src/Notepad/Infrastructure/Extensions/ConversionExtensions.cs
new file mode 100644
index 0000000..0266e58
--- /dev/null
+++ b/src/Notepad/Infrastructure/Extensions/ConversionExtensions.cs
@@ -0,0 +1,7 @@
+namespace Notepad.Infrastructure.Extensions {
+ public static class ConversionExtensions {
+ public static T DowncastTo<T>(this object objectToCast) {
+ return (T) objectToCast;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Extensions/EnumerableExtensions.cs b/src/Notepad/Infrastructure/Extensions/EnumerableExtensions.cs
new file mode 100644
index 0000000..d57c0e1
--- /dev/null
+++ b/src/Notepad/Infrastructure/Extensions/EnumerableExtensions.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace Notepad.Infrastructure.Extensions {
+ public static class EnumerableExtensions {
+ public static void Walk<T>(this IEnumerable<T> itemsToWalk) {
+ foreach (var item in itemsToWalk) {}
+ }
+
+ public static IEnumerable<T> ThatSatisfy<T>(this IEnumerable<T> itemsToPeekInto, Predicate<T> criteriaToSatisfy) {
+ foreach (var item in itemsToPeekInto) {
+ if (item.Satisfies(criteriaToSatisfy)) {
+ yield return item;
+ }
+ }
+ }
+
+ public static IEnumerable<T> SortedUsing<T>(this IEnumerable<T> itemsToSort, IComparer<T> sortingAlgorithm) {
+ var sortedItems = new List<T>(itemsToSort);
+ sortedItems.Sort(sortingAlgorithm);
+ return sortedItems;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Extensions/LoggingExtensions.cs b/src/Notepad/Infrastructure/Extensions/LoggingExtensions.cs
new file mode 100644
index 0000000..a05e2fc
--- /dev/null
+++ b/src/Notepad/Infrastructure/Extensions/LoggingExtensions.cs
@@ -0,0 +1,17 @@
+using System;
+using Notepad.Infrastructure.Logging;
+
+namespace Notepad.Infrastructure.Extensions {
+ public static class LoggingExtensions {
+ public static void LogError(this Exception errorToLog) {
+ Log.For(errorToLog).Error(errorToLog);
+ }
+
+ public static void LogInformational<T>(
+ this T typeToCreateLoggerFor,
+ string formattedMessage,
+ params object[] arguments) {
+ Log.For(typeToCreateLoggerFor).Informational(formattedMessage, arguments);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Extensions/SpecificationExtensions.cs b/src/Notepad/Infrastructure/Extensions/SpecificationExtensions.cs
new file mode 100644
index 0000000..c7ed7dc
--- /dev/null
+++ b/src/Notepad/Infrastructure/Extensions/SpecificationExtensions.cs
@@ -0,0 +1,14 @@
+using System;
+using Notepad.Infrastructure.Core;
+
+namespace Notepad.Infrastructure.Extensions {
+ public static class SpecificationExtensions {
+ public static bool Satisfies<T>(this T itemToValidate, Predicate<T> criteriaToSatisfy) {
+ return criteriaToSatisfy(itemToValidate);
+ }
+
+ public static bool Satisfies<T>(this T itemToValidate, ISpecification<T> criteriaToSatisfy) {
+ return itemToValidate.Satisfies(criteriaToSatisfy.IsSatisfiedBy);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Extensions/StringExtensions.cs b/src/Notepad/Infrastructure/Extensions/StringExtensions.cs
new file mode 100644
index 0000000..9c19f97
--- /dev/null
+++ b/src/Notepad/Infrastructure/Extensions/StringExtensions.cs
@@ -0,0 +1,13 @@
+using Notepad.Domain.FileSystem;
+
+namespace Notepad.Infrastructure.Extensions {
+ public static class StringExtensions {
+ public static string FormatWith(this string formattedString, params object[] arguments) {
+ return string.Format(formattedString, arguments);
+ }
+
+ public static IFilePath AsAnAbsoluteFilePath(this string rawFilePath) {
+ return new AbsoluteFilePath(rawFilePath);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Logging/ILogFactory.cs b/src/Notepad/Infrastructure/Logging/ILogFactory.cs
new file mode 100644
index 0000000..ce1d2e1
--- /dev/null
+++ b/src/Notepad/Infrastructure/Logging/ILogFactory.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace Notepad.Infrastructure.Logging {
+ public interface ILogFactory {
+ ILogger CreateFor(Type typeToCreateLoggerFor);
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Logging/ILogger.cs b/src/Notepad/Infrastructure/Logging/ILogger.cs
new file mode 100644
index 0000000..ac7dd6f
--- /dev/null
+++ b/src/Notepad/Infrastructure/Logging/ILogger.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace Notepad.Infrastructure.Logging {
+ public interface ILogger {
+ void Informational(string formattedString, params object[] arguments);
+ void Error(Exception e);
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Logging/Log.cs b/src/Notepad/Infrastructure/Logging/Log.cs
new file mode 100644
index 0000000..e8a3b4c
--- /dev/null
+++ b/src/Notepad/Infrastructure/Logging/Log.cs
@@ -0,0 +1,15 @@
+using Notepad.Infrastructure.Container;
+using Notepad.Infrastructure.Logging.Log4NetLogging;
+
+namespace Notepad.Infrastructure.Logging {
+ public static class Log {
+ public static ILogger For<T>(T typeToCreateLoggerFor) {
+ try {
+ return Resolve.DependencyFor<ILogFactory>().CreateFor(typeof (T));
+ }
+ catch {
+ return new Log4NetLogFactory().CreateFor(typeof (T));
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Logging/Log4NetLogging/Log4NetLogFactory.cs b/src/Notepad/Infrastructure/Logging/Log4NetLogging/Log4NetLogFactory.cs
new file mode 100644
index 0000000..0784a13
--- /dev/null
+++ b/src/Notepad/Infrastructure/Logging/Log4NetLogging/Log4NetLogFactory.cs
@@ -0,0 +1,20 @@
+using System;
+using System.IO;
+using log4net;
+using log4net.Config;
+
+namespace Notepad.Infrastructure.Logging.Log4NetLogging {
+ public class Log4NetLogFactory : ILogFactory {
+ public Log4NetLogFactory() {
+ XmlConfigurator.Configure(PathToConfigFile());
+ }
+
+ public ILogger CreateFor(Type typeToCreateLoggerFor) {
+ return new Log4NetLogger(LogManager.GetLogger(typeToCreateLoggerFor));
+ }
+
+ private FileInfo PathToConfigFile() {
+ return new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config.xml"));
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Logging/Log4NetLogging/Log4NetLogger.cs b/src/Notepad/Infrastructure/Logging/Log4NetLogging/Log4NetLogger.cs
new file mode 100644
index 0000000..5111622
--- /dev/null
+++ b/src/Notepad/Infrastructure/Logging/Log4NetLogging/Log4NetLogger.cs
@@ -0,0 +1,20 @@
+using System;
+using log4net;
+
+namespace Notepad.Infrastructure.Logging.Log4NetLogging {
+ public class Log4NetLogger : ILogger {
+ private readonly ILog log;
+
+ public Log4NetLogger(ILog log) {
+ this.log = log;
+ }
+
+ public void Informational(string formattedString, params object[] arguments) {
+ log.InfoFormat(formattedString, arguments);
+ }
+
+ public void Error(Exception e) {
+ log.Error(e.ToString());
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/Logging/LogSpecs.cs b/src/Notepad/Infrastructure/Logging/LogSpecs.cs
new file mode 100644
index 0000000..3e6aead
--- /dev/null
+++ b/src/Notepad/Infrastructure/Logging/LogSpecs.cs
@@ -0,0 +1,40 @@
+using MbUnit.Framework;
+using Notepad.Infrastructure.Container;
+using Rhino.Mocks;
+
+namespace Notepad.Infrastructure.Logging {
+ public class LogSpecs {}
+
+ [TestFixture]
+ public class when_creating_a_logger_for_a_particular_type_ {
+ private MockRepository mockery;
+ private ILogFactory factory;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ factory = mockery.DynamicMock<ILogFactory>();
+
+ var resolver = mockery.DynamicMock<IDependencyRegistry>();
+ SetupResult.For(resolver.FindAnImplementationOf<ILogFactory>()).Return(factory);
+
+ Resolve.InitializeWith(resolver);
+ }
+
+ [Test]
+ public void should_leverage_the_log_factory_to_create_a_logger_for_the_given_type() {
+ var logger = mockery.DynamicMock<ILogger>();
+ using (mockery.Record()) {
+ Expect
+ .Call(factory.CreateFor(GetType()))
+ .Return(logger)
+ .Repeat
+ .AtLeastOnce();
+ }
+
+ using (mockery.Playback()) {
+ Log.For(this);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Notepad/Infrastructure/System/IApplicationEnvironment.cs b/src/Notepad/Infrastructure/System/IApplicationEnvironment.cs
new file mode 100644
index 0000000..64cc737
--- /dev/null
+++ b/src/Notepad/Infrastructure/System/IApplicationEnvironment.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Notepad.Infrastructure.System {
+ public interface IApplicationEnvironment {
+ void ShutDown();
+ }
+
+ public class ApplicationEnvironment : IApplicationEnvironment {
+ public void ShutDown() {
+ Environment.Exit(Environment.ExitCode);
+ }
+ }
+} \ No newline at end of file