Commit c09b3aa

mokhan <mokhan@ce5e1baf-6525-42e4-a1b2-857ea38da20a>
2009-04-01 14:00:04
git-svn-id: https://svn.xp-dev.com/svn/mokhan-mo.money@130 ce5e1baf-6525-42e4-a1b2-857ea38da20a
1 parent a48c622
Changed files (5)
trunk
trunk/product/MyMoney/Infrastructure/caching/IIdentityMap.cs
@@ -1,9 +1,11 @@
+using System;
 using System.Collections.Generic;
 
 namespace MoMoney.Infrastructure.caching
 {
     public interface IIdentityMap<TKey, TValue>
     {
+        IEnumerable<TValue> all();
         void add(TKey key, TValue value);
         void update_the_item_for(TKey key, TValue new_value);
         bool contains_an_item_for(TKey key);
@@ -23,6 +25,11 @@ namespace MoMoney.Infrastructure.caching
             this.items_in_map = items_in_map;
         }
 
+        public IEnumerable<TValue> all()
+        {
+            throw new NotImplementedException();
+        }
+
         public void add(TKey key, TValue value)
         {
             items_in_map.Add(key, value);
trunk/product/MyMoney/Infrastructure/transactions2/ITransaction.cs
@@ -0,0 +1,11 @@
+using MoMoney.Domain.Core;
+
+namespace MoMoney.Infrastructure.transactions2
+{
+    public interface ITransaction
+    {
+        void add_transient<T>(T entity) where T : IEntity;
+        void commit_changes();
+        void rollback_changes();
+    }
+}
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/transactions2/Session.cs
@@ -1,24 +1,67 @@
+using System;
+using System.Collections.Generic;
 using MoMoney.Domain.Core;
+using MoMoney.Infrastructure.caching;
 
 namespace MoMoney.Infrastructure.transactions2
 {
-    public interface ISession
+    public interface ISession : IDisposable
     {
+        IEnumerable<T> all<T>();
         void save<T>(T entity) where T : IEntity;
+        void flush();
     }
 
     public class Session : ISession
     {
-        IIdentityMapFactory factory;
+        readonly IIdentityMapFactory factory;
+        ITransaction transaction;
+        readonly IDictionary<Type, object> maps;
 
-        public Session(IIdentityMapFactory factory)
+        public Session(IIdentityMapFactory factory, ITransaction transaction)
         {
             this.factory = factory;
+            this.transaction = transaction;
+            maps = new Dictionary<Type, object>();
+        }
+
+        public IEnumerable<T> all<T>()
+        {
+            return get_identity_map_for<T>().all();
         }
 
         public void save<T>(T entity) where T : IEntity
         {
-            factory.create_for<T>().add(entity.Id, entity);
+            create_map_for<T>().add(entity.Id, entity);
+            transaction.add_transient(entity);
+        }
+
+        public void flush()
+        {
+            transaction.commit_changes();
+            transaction = null;
+        }
+
+        public void Dispose()
+        {
+            if (null != transaction) transaction.rollback_changes();
+        }
+
+        IIdentityMap<Guid, T> get_identity_map_for<T>()
+        {
+            if (maps.ContainsKey(typeof (T)))
+            {
+                return (IIdentityMap<Guid, T>) maps[typeof (T)];
+            }
+            return create_map_for<T>();
         }
+
+        IIdentityMap<Guid, T> create_map_for<T>()
+        {
+            var map = factory.create_for<T>();
+            maps.Add(typeof (T), map);
+            return map;
+        }
+
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/transactions2/SessionSpecs.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using developwithpassion.bdd.contexts;
 using MoMoney.Domain.Core;
 using MoMoney.Infrastructure.caching;
@@ -13,15 +14,22 @@ namespace MoMoney.Infrastructure.transactions2
 
     public class behaves_like_session : concerns_for<ISession, Session>
     {
-        context c = () => { factory = the_dependency<IIdentityMapFactory>(); };
+        context c = () =>
+                        {
+                            factory = the_dependency<IIdentityMapFactory>();
+                            transaction = the_dependency<ITransaction>();
+                        };
 
         protected static IIdentityMapFactory factory;
+        protected static ITransaction transaction;
     }
 
-    public class when_saving_an_item_to_a_session : behaves_like_session
+    public class when_saving_a_transient_item_to_a_session : behaves_like_session
     {
         it should_add_the_entity_to_the_identity_map = () => map.was_told_to(x => x.add(guid, entity));
 
+        it should_add_the_item_to_the_current_transaction = () => transaction.was_told_to(x => x.add_transient(entity));
+
         context c = () =>
                         {
                             guid = Guid.NewGuid();
@@ -32,13 +40,69 @@ namespace MoMoney.Infrastructure.transactions2
                             when_the(factory).is_told_to(x => x.create_for<ITestEntity>()).it_will_return(map);
                         };
 
-        because b = () => { sut.save(entity); };
+        because b = () => sut.save(entity);
 
         static ITestEntity entity;
         static IIdentityMap<Guid, ITestEntity> map;
         static Guid guid;
     }
 
+    public class when_commiting_the_changes_made_in_a_session : behaves_like_session
+    {
+        it should_commit_all_the_changes_from_the_running_transaction =
+            () => transaction.was_told_to(x => x.commit_changes());
+
+        it should_not_rollback_any_changes_from_the_running_transaction =
+            () => transaction.was_not_told_to(x => x.rollback_changes());
+
+        because b = () =>
+                        {
+                            sut.flush();
+                            sut.Dispose();
+                        };
+    }
+
+    public class when_closing_a_session_before_flushing_the_changes : behaves_like_session
+    {
+        it should_rollback_any_changes_made_in_the_current_transaction =
+            () => transaction.was_told_to(x => x.rollback_changes());
+
+        because b = () => sut.Dispose();
+    }
+
+    public class when_retrieving_an_all_the_items_from_a_session_it_retrieve_all_the_items_from_the_cache :
+        behaves_like_session
+    {
+        it should_return_all_the_items_currently_loaded_in_the_cache = () => results.should_contain(entity);
+
+        it should_load_all_the_items_from_the_database = () =>
+                                                             {
+                                                                 ///?how
+                                                             };
+
+        context c = () => {
+                            guid = Guid.NewGuid();
+                            entity = an<ITestEntity>();
+                            map = an<IIdentityMap<Guid, ITestEntity>>();
+
+                            when_the(entity).is_told_to(x => x.Id).it_will_return(guid);
+                            when_the(factory).is_told_to(x => x.create_for<ITestEntity>()).it_will_return(map);
+                            when_the(map).is_told_to(x => x.all()).it_will_return(entity);
+        };
+
+        because b = () =>
+                        {
+                            sut.save(entity);
+                            results = sut.all<ITestEntity>();
+                        };
+
+        static IEnumerable<ITestEntity> results;
+        static ITestEntity entity;
+        static Guid guid;
+        static IIdentityMap<Guid, ITestEntity> map;
+    }
+
+
     public interface ITestEntity : IEntity
     {
     }
trunk/product/MyMoney/MyMoney.csproj
@@ -297,6 +297,7 @@
       <SubType>Component</SubType>
     </Compile>
     <Compile Include="Infrastructure\transactions2\IIdentityMapFactory.cs" />
+    <Compile Include="Infrastructure\transactions2\ITransaction.cs" />
     <Compile Include="Infrastructure\transactions2\Session.cs" />
     <Compile Include="Infrastructure\transactions2\SessionSpecs.cs" />
     <Compile Include="Infrastructure\transactions\IUnitOfWorkRegistrationFactory.cs" />