Commit 3c90f65

mo <email@solidware.ca>
2011-03-20 05:39:56
implemented the unit of work interceptor.
1 parent aff8394
product/desktop.ui/bootstrappers/Bootstrapper.cs
@@ -100,7 +100,7 @@ namespace solidware.financials.windows.ui.bootstrappers
 
         static void server_registration(ContainerBuilder builder)
         {
-            var interceptor = new UnitOfWorkInterceptor();
+            var interceptor = new UnitOfWorkInterceptor(null);
             builder.RegisterProxy<Handles<FamilyMemberToAdd>, AddNewFamilyMemberHandler>(interceptor);
             builder.RegisterProxy<Handles<FindAllFamily>, FindAllFamilyHandler>(interceptor);
             builder.RegisterType<InMemoryDatabase>().As<PersonRepository>().SingleInstance();
product/service/orm/Connection.cs
@@ -0,0 +1,6 @@
+namespace solidware.financials.service.orm
+{
+    public interface Connection
+    {
+    }
+}
\ No newline at end of file
product/service/orm/ConnectionFactory.cs
@@ -0,0 +1,7 @@
+namespace solidware.financials.service.orm
+{
+    public interface ConnectionFactory
+    {
+        Connection Open();
+    }
+}
\ No newline at end of file
product/service/orm/Disposable.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace solidware.financials.service.orm
+{
+    public interface Disposable : IDisposable
+    {
+    }
+}
\ No newline at end of file
product/service/orm/TypedKey.cs
@@ -0,0 +1,51 @@
+using System.Collections;
+using gorilla.utility;
+
+namespace solidware.financials.service.orm
+{
+    public class TypedKey<T> : Key<T>
+    {
+        public bool is_found_in(IDictionary items)
+        {
+            return items.Contains(create_key());
+        }
+
+        public T parse_from(IDictionary items)
+        {
+            return (T) items[create_key()];
+        }
+
+        public void remove_from(IDictionary items)
+        {
+            if (is_found_in(items)) items.Remove(create_key());
+        }
+
+        public void add_value_to(IDictionary items, T value)
+        {
+            items[create_key()] = value;
+        }
+
+        public bool Equals(TypedKey<T> obj)
+        {
+            return !ReferenceEquals(null, obj);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (TypedKey<T>)) return false;
+            return Equals((TypedKey<T>) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return GetType().GetHashCode();
+        }
+
+        string create_key()
+        {
+            return GetType().FullName;
+        }
+    }
+}
\ No newline at end of file
product/service/orm/UnitOfWork.cs
@@ -0,0 +1,7 @@
+namespace solidware.financials.service.orm
+{
+    public interface UnitOfWork : Disposable
+    {
+        void commit();
+    }
+}
\ No newline at end of file
product/service/orm/UnitOfWorkFactory.cs
@@ -0,0 +1,7 @@
+namespace solidware.financials.service.orm
+{
+    public interface UnitOfWorkFactory
+    {
+        UnitOfWork create();
+    }
+}
\ No newline at end of file
product/service/orm/UnitOfWorkInterceptor.cs
@@ -4,9 +4,20 @@ namespace solidware.financials.service.orm
 {
     public class UnitOfWorkInterceptor : IInterceptor
     {
+        readonly UnitOfWorkFactory unit_of_work_factory;
+
+        public UnitOfWorkInterceptor(UnitOfWorkFactory unit_of_work_factory)
+        {
+            this.unit_of_work_factory = unit_of_work_factory;
+        }
+
         public void Intercept(IInvocation invocation)
         {
-            invocation.Proceed();
+            using (var unit_of_work = unit_of_work_factory.create())
+            {
+                invocation.Proceed();
+                unit_of_work.commit();
+            }
         }
     }
 }
\ No newline at end of file
product/service/service.csproj
@@ -57,10 +57,16 @@
     <Compile Include="domain\Entity.cs" />
     <Compile Include="domain\Person.cs" />
     <Compile Include="handlers\FindAllFamilyHandler.cs" />
+    <Compile Include="orm\Connection.cs" />
+    <Compile Include="orm\ConnectionFactory.cs" />
     <Compile Include="orm\DB4OPersonRepository.cs" />
+    <Compile Include="orm\Disposable.cs" />
     <Compile Include="orm\InMemoryDatabase.cs" />
     <Compile Include="orm\LastOpened.cs" />
     <Compile Include="orm\PersonRepository.cs" />
+    <Compile Include="orm\TypedKey.cs" />
+    <Compile Include="orm\UnitOfWork.cs" />
+    <Compile Include="orm\UnitOfWorkFactory.cs" />
     <Compile Include="orm\UnitOfWorkInterceptor.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
product/specs/unit/service/orm/UnitOfWorkInterceptorSpecs.cs
@@ -0,0 +1,49 @@
+using Castle.DynamicProxy;
+using Machine.Specifications;
+using Rhino.Mocks;
+using solidware.financials.service.orm;
+
+namespace specs.unit.service.orm
+{
+    public class UnitOfWorkInterceptorSpecs
+    {
+        public abstract class concern
+        {
+            Establish context = () =>
+            {
+                unit_of_work_factory = Create.dependency<UnitOfWorkFactory>();
+                sut = new UnitOfWorkInterceptor(unit_of_work_factory);
+            };
+
+            static protected UnitOfWorkInterceptor sut;
+            static protected UnitOfWorkFactory unit_of_work_factory;
+        }
+
+        [Subject(typeof(UnitOfWorkInterceptor))]
+        public class when_starting_a_new_unit_of_work : concern
+        {
+            It should_proceed_with_the_invocation = () =>
+            {
+                invocation.AssertWasCalled(x => x.Proceed());
+            };
+
+            It should_commit_the_unit_of_work = () =>
+            {
+                unit_of_work.AssertWasCalled(x => x.commit());
+                unit_of_work.AssertWasCalled(x => x.Dispose());
+            };
+
+            Establish context = () =>
+            {
+                invocation = Create.an<IInvocation>();
+                unit_of_work = Create.an<UnitOfWork>();
+                unit_of_work_factory.Stub(x => x.create()).Return(unit_of_work);
+            };
+
+            Because of = () => { sut.Intercept(invocation); };
+
+            static IInvocation invocation;
+            static UnitOfWork unit_of_work;
+        }
+    }
+}
\ No newline at end of file
product/specs/specs.csproj
@@ -62,6 +62,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Create.cs" />
     <Compile Include="unit\infrastructure\ProxyFactorySpecs.cs" />
+    <Compile Include="unit\service\orm\UnitOfWorkInterceptorSpecs.cs" />
     <Compile Include="unit\ui\InMemoryApplicationStateSpecs.cs" />
     <Compile Include="unit\ui\presenters\AddFamilyMemberPresenterSpecs.cs" />
     <Compile Include="unit\ui\presenters\AddNewIncomeViewModelSpecs.cs" />
@@ -80,6 +81,10 @@
       <Project>{C3DF753C-7BB7-48E0-B87D-D37ED47EDF92}</Project>
       <Name>messages</Name>
     </ProjectReference>
+    <ProjectReference Include="..\service\service.csproj">
+      <Project>{9928913D-5BCE-422F-9A12-13A10ACE836D}</Project>
+      <Name>service</Name>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.