Commit d09c36c

mokhan <mokhan@ce5e1baf-6525-42e4-a1b2-857ea38da20a>
2009-03-16 02:39:37
broke a bunch of stuff but doing some major refactoring to how the unit of work is implemented.
git-svn-id: https://svn.xp-dev.com/svn/mokhan-mo.money@78 ce5e1baf-6525-42e4-a1b2-857ea38da20a
1 parent 9806b17
trunk/build/lib/app/object.list.view/ObjectListView.dll
Binary file
trunk/build/lib/app/object.list.view/ObjectListView.pdb
Binary file
trunk/product/MyMoney/DataAccess/core/IDatabaseGateway.cs
@@ -1,10 +1,9 @@
 using System.Collections.Generic;
 using MoMoney.Domain.Core;
-using MoMoney.Infrastructure.Logging;
 
 namespace MoMoney.DataAccess.core
 {
-    public interface IDatabaseGateway : ILoggable
+    public interface IDatabaseGateway
     {
         IEnumerable<T> all<T>() where T : IEntity;
         void save<T>(T item) where T : IEntity;
trunk/product/MyMoney/DataAccess/db40/ConnectionFactory.cs
@@ -5,14 +5,14 @@ namespace MoMoney.DataAccess.db40
 {
     public interface IConnectionFactory
     {
-        ISession open_connection_to(IFile the_path_to_the_database_file);
+        IObjectContainer open_connection_to(IFile the_path_to_the_database_file);
     }
 
     public class ConnectionFactory : IConnectionFactory
     {
-        public ISession open_connection_to(IFile the_path_to_the_database_file)
+        public IObjectContainer open_connection_to(IFile the_path_to_the_database_file)
         {
-            return new Session(Db4oFactory.OpenFile(the_path_to_the_database_file.path), the_path_to_the_database_file);
+            return Db4oFactory.OpenFile(the_path_to_the_database_file.path);
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/DataAccess/db40/EmptySession.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MoMoney.Domain.Core;
+using MoMoney.Infrastructure.Extensions;
+using MoMoney.Utility.Extensions;
+
+namespace MoMoney.DataAccess.db40
+{
+    public class EmptySession : ISession
+    {
+        readonly HashSet<object> items;
+        Guid session_id;
+
+        public EmptySession()
+        {
+            items = new HashSet<object>();
+            session_id = Guid.NewGuid();
+        }
+
+        public IEnumerable<T> query<T>() where T : IEntity
+        {
+            var enumerable = items
+                .where(x => x.is_an_implementation_of<T>())
+                .Select(x => x.downcast_to<T>());
+            this.log().debug("items in session: {0}", enumerable.Count());
+            enumerable.each(x => this.log().debug("session item {0}", x));
+            return enumerable;
+        }
+
+        public void save<T>(T item) where T : IEntity
+        {
+            if (query<T>().Count(x => x.Id.Equals(item.Id)) > 0)
+            {
+                this.log().debug("already added: {0}, from {1}", item, session_id);
+            }
+            this.log().debug("adding item: {0}, from {1}", item, session_id);
+            items.Add(item);
+        }
+
+        public void commit()
+        {
+            //items.Clear();
+        }
+    }
+}
\ No newline at end of file
trunk/product/MyMoney/DataAccess/db40/ObjectDatabaseGateway.cs
@@ -1,42 +1,33 @@
 using System.Collections.Generic;
-using System.Linq;
 using MoMoney.DataAccess.core;
 using MoMoney.Domain.Core;
-using MoMoney.Infrastructure.Extensions;
-using MoMoney.Utility.Extensions;
 
 namespace MoMoney.DataAccess.db40
 {
     public class ObjectDatabaseGateway : IDatabaseGateway
     {
-        readonly ISessionProvider provider;
+        readonly ISessionContext context;
 
-        public ObjectDatabaseGateway(ISessionProvider provider)
+        public ObjectDatabaseGateway(ISessionContext context)
         {
-            this.provider = provider;
+            this.context = context;
         }
 
         public IEnumerable<T> all<T>() where T : IEntity
         {
-            using (var container = open_session_with_database())
-            {
-                container.Query<T>().each(x => this.log().debug("found item: {0}", x));
-                return container.Query<T>().ToList();
-            }
+            return open_session_with_database().query<T>();
         }
 
         public void save<T>(T item) where T : IEntity
         {
-            using (var container = open_session_with_database())
-            {
-                container.Store(item);
-                container.Commit();
-            }
+            var session = open_session_with_database();
+            session.save(item);
+            //session.commit();
         }
 
         ISession open_session_with_database()
         {
-            return provider.get_session();
+            return context.current_session();
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/DataAccess/db40/ObjectDatabaseGatewaySpecs.cs
@@ -1,5 +1,4 @@
 using System.Collections.Generic;
-using Db4objects.Db4o;
 using developwithpassion.bdd.contexts;
 using MoMoney.DataAccess.core;
 using MoMoney.Domain.Core;
@@ -12,9 +11,9 @@ namespace MoMoney.DataAccess.db40
     [Concern(typeof (ObjectDatabaseGateway))]
     public abstract class behaves_like_a_object_repository : concerns_for<IDatabaseGateway, ObjectDatabaseGateway>
     {
-        context c = () => { provider = the_dependency<ISessionProvider>(); };
+        context c = () => { _context = the_dependency<ISessionContext>(); };
 
-        protected static ISessionProvider provider;
+        protected static ISessionContext _context;
     }
 
     public class when_loading_all_the_items_from_the_database : behaves_like_a_object_repository
@@ -31,8 +30,9 @@ namespace MoMoney.DataAccess.db40
                             second_item = an<IEntity>();
                             var session = an<ISession>();
 
-                            provider.is_told_to(x => x.get_session()).it_will_return(session);
-                            session.is_told_to(x => x.Query<IEntity>()).it_will_return(new List<IEntity> {first_item, second_item});
+                            _context.is_told_to(x => x.current_session()).it_will_return(session);
+                            session.is_told_to(x => x.query<IEntity>()).it_will_return(new List<IEntity>
+                                                                                           {first_item, second_item});
                         };
 
         because b = () => { result = sut.all<IEntity>(); };
trunk/product/MyMoney/DataAccess/db40/Session.cs
@@ -1,52 +1,49 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
 using Db4objects.Db4o;
-using MoMoney.Presentation.Model.Projects;
+using MoMoney.Domain.Core;
+using MoMoney.Infrastructure.Extensions;
 
 namespace MoMoney.DataAccess.db40
 {
-    public interface ISession : IDisposable
+    public interface ISession
     {
-        bool represents(IFile file);
-        IEnumerable<T> Query<T>();
-        void Store<T>(T item);
-        void Commit();
+        IEnumerable<T> query<T>() where T : IEntity;
+        void save<T>(T item) where T : IEntity;
+        void commit();
     }
 
     public class Session : ISession
     {
         readonly IObjectContainer connection;
-        readonly IFile path;
+        Guid session_id;
 
-        public Session(IObjectContainer connection, IFile path)
+        public Session(IObjectContainer connection)
         {
             this.connection = connection;
-            this.path = path;
+            session_id = Guid.NewGuid();
         }
 
-        public bool represents(IFile file)
-        {
-            return path.Equals(file);
-        }
-
-        public IEnumerable<T> Query<T>()
+        public IEnumerable<T> query<T>() where T : IEntity
         {
             return connection.Query<T>();
         }
 
-        public void Store<T>(T item)
+        public void save<T>(T item) where T : IEntity
         {
+            if (query<T>().Count(x => x.Id.Equals(item.Id)) > 0)
+            {
+                this.log().debug("already added: {0}, from {1}", item, session_id);
+            }
+            this.log().debug("adding item: {0}, {1} {2}", item, session_id, Thread.CurrentThread.ManagedThreadId);
             connection.Store(item);
         }
 
-        public void Commit()
+        public void commit()
         {
             connection.Commit();
         }
-
-        public void Dispose()
-        {
-            //connection.Dispose();
-        }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/DataAccess/db40/SessionContext.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+using Castle.Core;
+using Db4objects.Db4o;
+using MoMoney.Presentation.Model.Projects;
+
+namespace MoMoney.DataAccess.db40
+{
+    public interface ISessionContext
+    {
+        void start_session_for(IFile file);
+        ISession current_session();
+        void close_session_to(IFile file);
+    }
+
+    [Singleton]
+    public class SessionContext : ISessionContext
+    {
+        readonly IConnectionFactory connection_factory;
+        readonly IDictionary<IFile, IObjectContainer> sessions;
+        ISession session;
+
+        public SessionContext(IConnectionFactory connection_factory)
+        {
+            this.connection_factory = connection_factory;
+            session = new EmptySession();
+            sessions = new Dictionary<IFile, IObjectContainer>();
+        }
+
+        public void start_session_for(IFile file)
+        {
+            var container = connection_factory.open_connection_to(file);
+            sessions.Add(file, container);
+            session = new Session(container);
+        }
+
+        public ISession current_session()
+        {
+            if (null == session) session = new EmptySession();
+            return session;
+        }
+
+        public void close_session_to(IFile file)
+        {
+            if (!sessions.ContainsKey(file)) return;
+            sessions[file].Dispose();
+            sessions.Remove(file);
+        }
+    }
+}
\ No newline at end of file
trunk/product/MyMoney/DataAccess/db40/SessionProviderSpecs.cs โ†’ trunk/product/MyMoney/DataAccess/db40/SessionContextSpecs.cs
@@ -7,8 +7,8 @@ using MoMoney.Testing.spechelpers.core;
 
 namespace MoMoney.DataAccess.db40
 {
-    [Concern(typeof (SessionProvider))]
-    public abstract class behaves_like_a_session_factory : concerns_for<ISessionProvider, SessionProvider>
+    [Concern(typeof (SessionContext))]
+    public abstract class behaves_like_a_session_factory : concerns_for<ISessionContext, SessionContext>
     {
         context c = () =>
                         {
@@ -22,23 +22,21 @@ namespace MoMoney.DataAccess.db40
 
     public class when_creating_a_new_session_to_a_db40_database : behaves_like_a_session_factory
     {
-        it should_open_a_new_connection_to_the_database = () => result.should_be_equal_to(session);
+        it should_open_a_new_connection_to_the_database = () => result.should_be_an_instance_of<ISession>();
 
         context c =
             () =>
                 {
                     var the_path_to_the_database_file = an<IFile>();
-                    session = an<ISession>();
+                    session = an<IObjectContainer>();
 
-                    database_configuration.is_told_to(x => x.path_to_the_database()).it_will_return(
-                        the_path_to_the_database_file);
-                    connection_factory.is_told_to(x => x.open_connection_to(the_path_to_the_database_file)).
-                        it_will_return(session);
+                    database_configuration.is_told_to(x => x.path_to_the_database()).it_will_return( the_path_to_the_database_file);
+                    connection_factory.is_told_to(x => x.open_connection_to(the_path_to_the_database_file)). it_will_return(session);
                 };
 
-        because b = () => { result = sut.get_session(); };
+        because b = () => { result = sut.current_session(); };
 
         static ISession result;
-        static ISession session;
+        static IObjectContainer session;
     }
 }
\ No newline at end of file
trunk/product/MyMoney/DataAccess/db40/SessionProvider.cs
@@ -1,35 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-
-namespace MoMoney.DataAccess.db40
-{
-    public interface ISessionProvider
-    {
-        ISession get_session();
-    }
-
-    public class SessionProvider : ISessionProvider
-    {
-        readonly IDatabaseConfiguration database_configuration;
-        readonly IConnectionFactory connection_factory;
-        readonly IList<ISession> sessions;
-
-        public SessionProvider(IDatabaseConfiguration database_configuration, IConnectionFactory connection_factory)
-        {
-            this.database_configuration = database_configuration;
-            this.connection_factory = connection_factory;
-            sessions = new List<ISession>();
-        }
-
-        public ISession get_session()
-        {
-            var session = sessions.SingleOrDefault(x => x.represents(database_configuration.path_to_the_database()));
-            if (null == session)
-            {
-                session = connection_factory.open_connection_to(database_configuration.path_to_the_database());
-                sessions.Add(session);
-            }
-            return session;
-        }
-    }
-}
\ No newline at end of file
trunk/product/MyMoney/Domain/accounting/billing/Company.cs
@@ -33,7 +33,7 @@ namespace MoMoney.Domain.accounting.billing
 
         public override string ToString()
         {
-            return name;
+            return base.ToString() + " " + name;
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Domain/Core/Entity.cs
@@ -1,5 +1,6 @@
 using System;
 using MoMoney.Infrastructure.transactions;
+using MoMoney.Utility.Extensions;
 
 namespace MoMoney.Domain.Core
 {
@@ -38,5 +39,10 @@ namespace MoMoney.Domain.Core
         {
             return Id.GetHashCode();
         }
+
+        public override string ToString()
+        {
+            return "{0} id: {1}".formatted_using(base.ToString(), Id);
+        }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/eventing/EventAggregator.cs
@@ -35,12 +35,8 @@ namespace MoMoney.Infrastructure.eventing
         {
             get_list_for<Event>()
                 .Select(x => x.downcast_to<IEventSubscriber<Event>>())
-                .each(x =>
-                          {
-                              this.log().debug("publishing event {0} to {1}", typeof (Event).Name, x.GetType().FullName);
-                              x.notify(the_event_to_broadcast);
-                          }
-                );
+                //.Select(x => log_and_return(x))
+                .each(x => x.notify(the_event_to_broadcast));
         }
 
         public void publish<Event>() where Event : IEvent, new()
@@ -56,5 +52,11 @@ namespace MoMoney.Infrastructure.eventing
             }
             return subscribers[typeof (Event).FullName];
         }
+
+        IEventSubscriber<Event> log_and_return<Event>(IEventSubscriber<Event> x) where Event : IEvent
+        {
+            this.log().debug("publishing event {0} to {1}", typeof (Event).Name, x.GetType().FullName);
+            return x;
+        }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/interceptors/UnitOfWorkInterceptor.cs
@@ -22,14 +22,11 @@ namespace MoMoney.Infrastructure.interceptors
 
         public void Intercept(IInvocation invocation)
         {
-            using (registry)
+            invocation.Proceed();
+            if (registry.has_changes_to_commit())
             {
-                invocation.Proceed();
-                if (registry.has_changes_to_commit())
-                {
-                    registry.commit_all();
-                    broker.publish<unsaved_changes_event>();
-                }
+                registry.commit_all();
+                broker.publish<unsaved_changes_event>();
             }
         }
     }
trunk/product/MyMoney/Infrastructure/interceptors/UnitOfWorkInterceptorSpecs.cs
@@ -1,7 +0,0 @@
-namespace MoMoney.Infrastructure.interceptors
-{
-    public class UnitOfWorkInterceptorSpecs
-    {
-        
-    }
-}
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/transactions/unit_of_work.cs
@@ -1,8 +1,9 @@
 using System;
-using System.Linq;
 using System.Collections.Generic;
+using System.Linq;
 using MoMoney.DataAccess.core;
 using MoMoney.Domain.Core;
+using MoMoney.Infrastructure.Extensions;
 using MoMoney.Utility.Extensions;
 
 namespace MoMoney.Infrastructure.transactions
@@ -20,25 +21,27 @@ namespace MoMoney.Infrastructure.transactions
 
     public class unit_of_work<T> : IUnitOfWork<T> where T : IEntity
     {
-        readonly IDatabaseGateway repository;
+        readonly IDatabaseGateway gateway;
         readonly IUnitOfWorkRegistrationFactory<T> factory;
         readonly IList<IUnitOfWorkRegistration<T>> registered_items;
 
         public unit_of_work(IDatabaseGateway repository, IUnitOfWorkRegistrationFactory<T> factory)
         {
-            this.repository = repository;
+            gateway = repository;
             this.factory = factory;
             registered_items = new List<IUnitOfWorkRegistration<T>>();
         }
 
         public void register(T entity)
         {
+            this.log().debug("registering: {0}", entity);
             registered_items.Add(factory.map_from(entity));
         }
 
         public void commit()
         {
-            registered_items.each(x => repository.save(x.current));
+            this.log().debug("commiting: {0}", typeof(T));
+            registered_items.each(x => { if (x.contains_changes()) gateway.save(x.current); });
         }
 
         public bool is_dirty()
@@ -51,5 +54,4 @@ namespace MoMoney.Infrastructure.transactions
             registered_items.Clear();
         }
     }
-
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Menu/File/Commands/CloseProjectCommand.cs
@@ -26,12 +26,12 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
 
         public void saved()
         {
-            project.close();
+            project.close_project();
         }
 
         public void not_saved()
         {
-            project.close();
+            project.close_project();
         }
 
         public void cancelled()
trunk/product/MyMoney/Presentation/Model/Menu/File/Commands/NewCommand.cs
@@ -25,12 +25,12 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
 
         public void saved()
         {
-            current_project.start_a_new_project();
+            current_project.start_new_project();
         }
 
         public void not_saved()
         {
-            current_project.start_a_new_project();
+            current_project.start_new_project();
         }
 
         public void cancelled()
trunk/product/MyMoney/Presentation/Model/Menu/File/Commands/new_command_specs.cs โ†’ trunk/product/MyMoney/Presentation/Model/Menu/File/Commands/NewCommandSpecs.cs
@@ -32,14 +32,14 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
 
     public class when_starting_a_new_project_after_saving_a_previous_one : behaves_like_new_command
     {
-        it should_start_a_new_project = () => current_project.was_told_to(x => x.start_a_new_project());
+        it should_start_a_new_project = () => current_project.was_told_to(x => x.start_new_project());
 
         because b = () => sut.saved();
     }
 
     public class when_starting_a_new_project_after_declining_to_save_a_previous_one : behaves_like_new_command
     {
-        it should_start_a_new_project = () => current_project.was_told_to(x => x.start_a_new_project());
+        it should_start_a_new_project = () => current_project.was_told_to(x => x.start_new_project());
 
         because b = () => sut.not_saved();
     }
@@ -48,7 +48,7 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
         behaves_like_new_command
     {
         it should_not_start_a_new_project =
-            () => current_project.should_not_have_been_asked_to(x => x.start_a_new_project());
+            () => current_project.should_not_have_been_asked_to(x => x.start_new_project());
 
         because b = () => sut.cancelled();
     }
trunk/product/MyMoney/Presentation/Model/Menu/File/Commands/OpenCommand.cs
@@ -42,7 +42,7 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
 
         void open_project()
         {
-            project.open(view.tell_me_the_path_to_the_file());
+            project.open_project_from(view.tell_me_the_path_to_the_file());
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Menu/File/Commands/OpenCommandSpecs.cs
@@ -36,7 +36,7 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
     public class when_attempting_to_open_an_existing_project_after_saving_the_previous_project :
         behaves_like_command_to_open_a_project
     {
-        it should_open_the_project_at_the_file_path_specified = () => project.was_told_to(x => x.open(file_path));
+        it should_open_the_project_at_the_file_path_specified = () => project.was_told_to(x => x.open_project_from(file_path));
 
         //it will_re_load_the_application_shell = () => command.was_told_to(x => x.run());
 
@@ -54,7 +54,7 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
     public class when_opening_a_project_after_declining_to_save_the_previous_project :
         behaves_like_command_to_open_a_project
     {
-        it should_open_the_project_at_the_file_path_specified = () => project.was_told_to(x => x.open(file_path));
+        it should_open_the_project_at_the_file_path_specified = () => project.was_told_to(x => x.open_project_from(file_path));
 
         //it will_re_load_the_application_shell = () => command.was_told_to(x => x.run());
 
@@ -74,7 +74,7 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
             behaves_like_command_to_open_a_project
     {
         it should_not_open_the_project_at_the_file_path_specified =
-            () => project.should_not_have_been_asked_to(x => x.open(file_path));
+            () => project.should_not_have_been_asked_to(x => x.open_project_from(file_path));
 
         //it will_not_re_load_the_application_shell = () => command.should_not_have_been_asked_to(x => x.run());
 
trunk/product/MyMoney/Presentation/Model/Menu/File/Commands/save_as_command.cs
@@ -21,7 +21,7 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
 
         public void run()
         {
-            current_project.save_to(view.tell_me_the_path_to_the_file());
+            current_project.save_project_to(view.tell_me_the_path_to_the_file());
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Menu/File/Commands/save_as_command_specs.cs
@@ -10,7 +10,7 @@ namespace MoMoney.Presentation.Model.Menu.File.Commands
     [Concern(typeof (save_as_command))]
     public class when_saving_the_current_project_to_a_new_file_path : concerns_for<ISaveAsCommand, save_as_command>
     {
-        it should_save_the_current_project_to_the_new_path = () => current_project.was_told_to(x => x.save_to(new_path));
+        it should_save_the_current_project_to_the_new_path = () => current_project.was_told_to(x => x.save_project_to(new_path));
 
         context c = () =>
                         {
trunk/product/MyMoney/Presentation/Model/Projects/CurrentProject.cs
@@ -1,38 +1,38 @@
 using Castle.Core;
 using MoMoney.DataAccess.db40;
 using MoMoney.Infrastructure.eventing;
+using MoMoney.Infrastructure.transactions;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Utility.Extensions;
 
 namespace MoMoney.Presentation.Model.Projects
 {
-    public interface IProject : IEventSubscriber<unsaved_changes_event>
+    public interface IProject // : IEventSubscriber<unsaved_changes_event>
     {
         string name();
-        void start_a_new_project();
-        void open(IFile file);
-        void save_to(IFile new_file);
-        bool has_been_saved_at_least_once();
+        void start_new_project();
+        void open_project_from(IFile file);
         void save_changes();
+        void save_project_to(IFile new_file);
+        void close_project();
+        bool has_been_saved_at_least_once();
         bool has_unsaved_changes();
-        bool is_open();
-        void close();
     }
 
     [Singleton]
     public class CurrentProject : IProject
     {
-        readonly IDatabaseConfiguration configuration;
         readonly IEventAggregator broker;
+        readonly IUnitOfWorkRegistry registry;
+        readonly ISessionContext context;
         IFile current_file;
         bool is_project_open = false;
-        bool changes_to_save = false;
 
-        public CurrentProject(IDatabaseConfiguration configuration, IEventAggregator broker)
+        public CurrentProject(IEventAggregator broker, IUnitOfWorkRegistry registry, ISessionContext _context)
         {
             this.broker = broker;
-            this.configuration = configuration;
-            broker.subscribe_to(this);
+            this.registry = registry;
+            this.context = _context;
         }
 
         public string name()
@@ -40,71 +40,59 @@ namespace MoMoney.Presentation.Model.Projects
             return has_been_saved_at_least_once() ? current_file.path : "untitled.mo";
         }
 
-        public void open(IFile file)
+        public void start_new_project()
         {
-            if (!file.does_the_file_exist()) return;
-            if (is_open())
-            {
-                close();
-            }
-
-            current_file = file;
+            close_project();
             is_project_open = true;
-            configuration.change_path_to(file);
-            changes_to_save = false;
+            current_file = null;
             broker.publish(new new_project_opened(name()));
         }
 
-        public void start_a_new_project()
+        public void open_project_from(IFile file)
         {
-            if (is_open())
-            {
-                close();
-            }
+            if (!file.does_the_file_exist()) return;
+            close_project();
+            current_file = file;
             is_project_open = true;
-            current_file = null;
-            changes_to_save = false;
+            context.start_session_for(current_file);
             broker.publish(new new_project_opened(name()));
         }
 
-        public void save_to(IFile new_file)
+        public void save_changes()
         {
-            if (new_file.path.is_blank())
-            {
-                return;
-            }
-            current_file = new_file;
-            configuration.change_path_to(new_file);
-            save_changes();
+            ensure_that_a_path_to_save_to_has_been_specified();
+            registry.commit_all();
+            registry.Dispose();
+            context.current_session().commit();
+            broker.publish<saved_changes_event>();
         }
 
-        public bool has_been_saved_at_least_once()
+        public void save_project_to(IFile new_file)
         {
-            return current_file != null;
-        }
+            if (new_file.path.is_blank()) return;
 
-        public void save_changes()
-        {
-            ensure_that_a_path_to_save_to_has_been_specified();
-            changes_to_save = false;
-            broker.publish<saved_changes_event>();
+            context.start_session_for(new_file);
+            current_file = new_file;
+            save_changes();
         }
 
-        public bool has_unsaved_changes()
+        public void close_project()
         {
-            return changes_to_save;
+            if (!is_project_open) return;
+            registry.Dispose();
+            context.close_session_to(current_file);
+            is_project_open = false;
+            broker.publish<closing_project_event>();
         }
 
-        public bool is_open()
+        public bool has_been_saved_at_least_once()
         {
-            return is_project_open;
+            return current_file != null;
         }
 
-        public void close()
+        public bool has_unsaved_changes()
         {
-            is_project_open = false;
-            changes_to_save = false;
-            broker.publish<closing_project_event>();
+            return registry.has_changes_to_commit();
         }
 
         void ensure_that_a_path_to_save_to_has_been_specified()
@@ -114,10 +102,5 @@ namespace MoMoney.Presentation.Model.Projects
                 throw new file_not_specified_exception();
             }
         }
-
-        public void notify(unsaved_changes_event message)
-        {
-            changes_to_save = true;
-        }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Projects/CurrentProjectSpecs.cs
@@ -38,7 +38,7 @@ namespace MoMoney.Presentation.Model.Projects
 
         because b = () =>
                         {
-                            sut.open(file_to_update);
+                            sut.open_project_from(file_to_update);
                             sut.save_changes();
                         };
 
@@ -70,8 +70,8 @@ namespace MoMoney.Presentation.Model.Projects
 
         because b = () =>
                         {
-                            sut.open(original_file);
-                            sut.save_to(new_file);
+                            sut.open_project_from(original_file);
+                            sut.save_project_to(new_file);
                         };
 
         static IFile original_file;
@@ -91,7 +91,7 @@ namespace MoMoney.Presentation.Model.Projects
 
         because b = () =>
                         {
-                            sut.open(invalid_file);
+                            sut.open_project_from(invalid_file);
                             result = sut.has_been_saved_at_least_once();
                         };
 
@@ -112,7 +112,7 @@ namespace MoMoney.Presentation.Model.Projects
 
         because b = () =>
                         {
-                            sut.save_to(invalid_file);
+                            sut.save_project_to(invalid_file);
                             result = sut.has_been_saved_at_least_once();
                         };
 
@@ -128,7 +128,7 @@ namespace MoMoney.Presentation.Model.Projects
                             when_the(file).is_told_to(x => x.does_the_file_exist()).it_will_return(true);
                         };
 
-        because b = () => sut.open(file);
+        because b = () => sut.open_project_from(file);
 
         static IFile file;
     }
@@ -154,9 +154,9 @@ namespace MoMoney.Presentation.Model.Projects
 
         because b = () =>
                         {
-                            sut.start_a_new_project();
-                            sut.save_to(file);
-                            sut.notify(message);
+                            sut.start_new_project();
+                            sut.save_project_to(file);
+                            //sut.notify(message);
                             result = sut.has_unsaved_changes();
                         };
 
@@ -171,8 +171,8 @@ namespace MoMoney.Presentation.Model.Projects
 
         because b = () =>
                         {
-                            sut.start_a_new_project();
-                            sut.start_a_new_project();
+                            sut.start_new_project();
+                            sut.start_new_project();
                         };
     }
 
@@ -188,8 +188,8 @@ namespace MoMoney.Presentation.Model.Projects
 
         because b = () =>
                         {
-                            sut.open(file);
-                            sut.start_a_new_project();
+                            sut.open_project_from(file);
+                            sut.start_new_project();
                         };
 
         static IFile file;
trunk/product/MyMoney/Presentation/Model/Projects/file.cs
@@ -32,11 +32,11 @@ namespace MoMoney.Presentation.Model.Projects
             return file.path;
         }
 
-        public bool Equals(ApplicationFile obj)
+        public bool Equals(ApplicationFile other)
         {
-            if (ReferenceEquals(null, obj)) return false;
-            if (ReferenceEquals(this, obj)) return true;
-            return Equals(obj.path, path);
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return Equals(other.path, path);
         }
 
         public override bool Equals(object obj)
trunk/product/MyMoney/Presentation/Presenters/Shell/UnhandledErrorPresenter.cs
@@ -1,4 +1,5 @@
 using MoMoney.Infrastructure.eventing;
+using MoMoney.Infrastructure.Extensions;
 using MoMoney.Presentation.Core;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Presenters.Commands;
@@ -37,6 +38,7 @@ namespace MoMoney.Presentation.Presenters.Shell
 
         public void restart_application()
         {
+            this.log().debug("restart the application");
             restart.run();
         }
     }
trunk/product/MyMoney/Presentation/Presenters/AddCompanyPresenter.cs
@@ -45,7 +45,7 @@ namespace MoMoney.Presentation.Presenters
 
         private bool company_has_already_been_registered(register_new_company dto)
         {
-            return tasks.all_companys().Count(x => x.name.Equals(dto.company_name)) > 0;
+            return tasks.all_companys().Count(x => x.name.is_equal_to_ignoring_case(dto.company_name)) > 0;
         }
 
         private string create_error_message_from(register_new_company dto)
trunk/product/MyMoney/Presentation/Views/core/ApplicationWindow.cs
@@ -16,6 +16,7 @@ namespace MoMoney.Presentation.Views.core
         {
             InitializeComponent();
             Icon = ApplicationIcons.Application;
+            base.DoubleBuffered = true;
             SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
         }
 
trunk/product/MyMoney/Presentation/Views/Shell/LogFileView.Designer.cs
@@ -33,20 +33,26 @@
             // 
             // ux_log_file
             // 
+            this.ux_log_file.BackColor = System.Drawing.Color.Black;
             this.ux_log_file.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.ux_log_file.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.ux_log_file.ForeColor = System.Drawing.Color.White;
             this.ux_log_file.Location = new System.Drawing.Point(0, 0);
+            this.ux_log_file.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
             this.ux_log_file.Multiline = true;
             this.ux_log_file.Name = "ux_log_file";
-            this.ux_log_file.Size = new System.Drawing.Size(292, 266);
+            this.ux_log_file.Size = new System.Drawing.Size(389, 327);
             this.ux_log_file.TabIndex = 0;
             // 
             // LogFileView
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(292, 266);
+            this.ClientSize = new System.Drawing.Size(389, 327);
             this.Controls.Add(this.ux_log_file);
+            this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
             this.Name = "LogFileView";
+            this.TabText = "LogFileView";
             this.Text = "LogFileView";
             this.ResumeLayout(false);
             this.PerformLayout();
trunk/product/MyMoney/Presentation/Views/Shell/UnhandledErrorView.cs
@@ -21,8 +21,11 @@ namespace MoMoney.Presentation.Views.Shell
 
         public void attach_to(IUnhandledErrorPresenter presenter)
         {
-            close_button.Click += (sender, args) => Close();
-            restart_button.Click += (sender, args) => presenter.restart_application();
+            on_ui_thread(() =>
+                             {
+                                 close_button.Click += (sender, args) => Close();
+                                 restart_button.Click += (sender, args) => presenter.restart_application();
+                             });
         }
 
         public void display(Exception exception)
trunk/product/MyMoney/Presentation/Views/AddCompanyView.cs
@@ -1,9 +1,9 @@
-using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Windows.Forms;
 using MoMoney.Domain.accounting.billing;
+using MoMoney.Infrastructure.Extensions;
 using MoMoney.Presentation.Databindings;
 using MoMoney.Presentation.Model.interaction;
 using MoMoney.Presentation.Presenters;
@@ -41,13 +41,15 @@ namespace MoMoney.Presentation.Views
             listView2.View = View.Details;
             listView2.Columns.Add("Name");
             ux_company_search_textbox.TextChanged += (sender, args) =>
-            {
-                var foundItem = listView2.FindItemWithText(ux_company_search_textbox.Text, false, 0, true);
-                if (foundItem != null)
-                {
-                    listView2.TopItem = foundItem;
-                }
-            };
+                                                         {
+                                                             var foundItem =
+                                                                 listView2.FindItemWithText(
+                                                                     ux_company_search_textbox.Text, false, 0, true);
+                                                             if (foundItem != null)
+                                                             {
+                                                                 listView2.TopItem = foundItem;
+                                                             }
+                                                         };
         }
 
         public void attach_to(IAddCompanyPresenter presenter)
@@ -59,13 +61,24 @@ namespace MoMoney.Presentation.Views
 
         public void display(IEnumerable<ICompany> companies)
         {
+            this.log().debug("companys to display {0}", companies.Count());
+            if (companies.Count() > 0)
+            {
+                //this.log().debug("companys 1 display {0}", companies.ElementAt(0));
+                //this.log().debug("companys 2 display {0}", companies.ElementAt(1));
+                companies.each(x => this.log().debug("company {0}", x));
+            }
             ux_companys_listing.DataSource = companies.databind();
 
             listView1.Items.Clear();
-            listView1.Items.AddRange(companies.Select(x => new ListViewItem(x.name, 0)).ToArray());
+            listView1.Items.AddRange(companies.Select(x => new ListViewItem(x.name, 2)).ToArray());
 
             listView2.Items.Clear();
             listView2.Items.AddRange(companies.Select(x => new ListViewItem(x.name)).ToArray());
+
+            //var tlist = new TypedObjectListView<ICompany>(objectListView1);
+            //tlist.GetColumn(0).AspectGetter = (ICompany x) => x.name;
+            objectListView1.SetObjects(companies.ToList());
         }
 
         public void notify(params notification_message[] messages)
trunk/product/MyMoney/Presentation/Views/AddCompanyView.Designer.cs
@@ -41,6 +41,7 @@ namespace MoMoney.Presentation.Views
             this.listView1 = new System.Windows.Forms.ListView();
             this.ux_company_search_textbox = new System.Windows.Forms.TextBox();
             this.listView2 = new System.Windows.Forms.ListView();
+            this.objectListView1 = new BrightIdeasSoftware.ObjectListView();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonHeaderGroup1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonHeaderGroup1.Panel)).BeginInit();
             this.kryptonHeaderGroup1.Panel.SuspendLayout();
@@ -58,6 +59,7 @@ namespace MoMoney.Presentation.Views
             this.kryptonSplitContainer2.Panel2.SuspendLayout();
             this.kryptonSplitContainer2.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.objectListView1)).BeginInit();
             this.SuspendLayout();
             // 
             // kryptonHeaderGroup1
@@ -90,6 +92,7 @@ namespace MoMoney.Presentation.Views
             // 
             // kryptonSplitContainer1.Panel1
             // 
+            this.kryptonSplitContainer1.Panel1.Controls.Add(this.objectListView1);
             this.kryptonSplitContainer1.Panel1.Controls.Add(this.listView2);
             this.kryptonSplitContainer1.Panel1.Controls.Add(this.ux_company_search_textbox);
             this.kryptonSplitContainer1.Panel1.Controls.Add(this.listView1);
@@ -219,10 +222,20 @@ namespace MoMoney.Presentation.Views
             // 
             this.listView2.Location = new System.Drawing.Point(28, 417);
             this.listView2.Name = "listView2";
-            this.listView2.Size = new System.Drawing.Size(706, 249);
+            this.listView2.Size = new System.Drawing.Size(706, 80);
             this.listView2.TabIndex = 23;
             this.listView2.UseCompatibleStateImageBehavior = false;
             // 
+            // objectListView1
+            // 
+            this.objectListView1.ItemRenderer = null;
+            this.objectListView1.Location = new System.Drawing.Point(28, 514);
+            this.objectListView1.Name = "objectListView1";
+            this.objectListView1.Size = new System.Drawing.Size(706, 203);
+            this.objectListView1.TabIndex = 24;
+            this.objectListView1.UseCompatibleStateImageBehavior = false;
+            this.objectListView1.View = System.Windows.Forms.View.Details;
+            // 
             // AddCompanyView
             // 
             this.AcceptButton = this.ux_submit_button;
@@ -254,6 +267,7 @@ namespace MoMoney.Presentation.Views
             ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2)).EndInit();
             this.kryptonSplitContainer2.ResumeLayout(false);
             ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.objectListView1)).EndInit();
             this.ResumeLayout(false);
 
         }
@@ -272,6 +286,7 @@ namespace MoMoney.Presentation.Views
         private System.Windows.Forms.ListView listView1;
         private System.Windows.Forms.TextBox ux_company_search_textbox;
         private System.Windows.Forms.ListView listView2;
+        private BrightIdeasSoftware.ObjectListView objectListView1;
 
     }
 }
\ No newline at end of file
trunk/product/MyMoney/MyMoney.csproj
@@ -99,6 +99,10 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\build\tools\mbunit\MbUnit.Framework.dll</HintPath>
     </Reference>
+    <Reference Include="ObjectListView, Version=2.1.0.26964, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\build\lib\app\object.list.view\ObjectListView.dll</HintPath>
+    </Reference>
     <Reference Include="PresentationCore">
       <RequiredTargetFramework>3.0</RequiredTargetFramework>
     </Reference>
@@ -154,6 +158,7 @@
   <ItemGroup>
     <Compile Include="DataAccess\db40\ConnectionFactory.cs" />
     <Compile Include="DataAccess\db40\DatabaseConfiguration.cs" />
+    <Compile Include="DataAccess\db40\EmptySession.cs" />
     <Compile Include="DataAccess\db40\ObjectDatabaseGateway.cs" />
     <Compile Include="DataAccess\db40\ObjectDatabaseGatewaySpecs.cs" />
     <Compile Include="DataAccess\db40\Session.cs" />
@@ -172,8 +177,8 @@
     <Compile Include="Domain\Core\Entity.cs" />
     <Compile Include="Domain\Core\date.cs" />
     <Compile Include="DataAccess\core\IDatabaseGateway.cs" />
-    <Compile Include="DataAccess\db40\SessionProvider.cs" />
-    <Compile Include="DataAccess\db40\SessionProviderSpecs.cs" />
+    <Compile Include="DataAccess\db40\SessionContext.cs" />
+    <Compile Include="DataAccess\db40\SessionContextSpecs.cs" />
     <Compile Include="Domain\accounting\billing\billing_extensions.cs" />
     <Compile Include="Domain\accounting\billing\Company.cs" />
     <Compile Include="Domain\accounting\billing\company_specs.cs" />
@@ -218,7 +223,6 @@
     <Compile Include="Infrastructure\interceptors\RaiseEventInterceptor.cs" />
     <Compile Include="Infrastructure\interceptors\SynchronizedInterceptor.cs" />
     <Compile Include="Infrastructure\interceptors\UnitOfWorkInterceptor.cs" />
-    <Compile Include="Infrastructure\interceptors\UnitOfWorkInterceptorSpecs.cs" />
     <Compile Include="Infrastructure\Logging\ILoggable.cs" />
     <Compile Include="Infrastructure\proxies\IConstraintSelector.cs" />
     <Compile Include="Infrastructure\proxies\IInterceptorConstraint.cs" />
@@ -279,7 +283,7 @@
     <Compile Include="Presentation\Model\keyboard\ShortcutKey.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\CloseProjectCommand.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\close_window_command.cs" />
-    <Compile Include="Presentation\Model\Menu\File\Commands\new_command_specs.cs" />
+    <Compile Include="Presentation\Model\Menu\File\Commands\NewCommandSpecs.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\SaveChangesCommand.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\save_as_command_specs.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\save_command_specs.cs" />