Commit 9451070

mo <email@solidware.ca>
2011-03-20 16:21:37
figured out a way to get the db4o connection to work.
1 parent 9c9271d
product/desktop.ui/bootstrappers/Bootstrapper.cs
@@ -100,13 +100,25 @@ namespace solidware.financials.windows.ui.bootstrappers
 
         static void server_registration(ContainerBuilder builder)
         {
-            var interceptor = new UnitOfWorkInterceptor(null);
-            builder.RegisterProxy<Handles<FamilyMemberToAdd>, AddNewFamilyMemberHandler>(interceptor);
-            builder.RegisterProxy<Handles<FindAllFamily>, FindAllFamilyHandler>(interceptor);
-            builder.RegisterType<InMemoryDatabase>().As<PersonRepository>().SingleInstance();
+            //builder.RegisterType<InMemoryDatabase>().As<PersonRepository>().SingleInstance();
+            builder.RegisterType<DB4OPersonRepository>().As<PersonRepository>().SingleInstance();
             builder.RegisterType<ScopedContext>().As<Context>().SingleInstance();
+            //builder.Register(x => new SimpleContext(new Hashtable())).As<Context>().SingleInstance();
             builder.RegisterType<PerThreadScopedStorage>().As<IScopedStorage>();
             builder.RegisterType<CurrentThread>().As<IThread>();
+            builder.Register(x =>
+            {
+                return Lazy.load(() =>
+                {
+                    var context = Resolve.the<Context>();
+                    var key = new TypedKey<Connection>();
+                    return context.value_for(key);
+                });
+            });
+
+            var interceptor = new UnitOfWorkInterceptor(new DB40UnitOfWorkFactory(new DB4OConnectionFactory(), Lazy.load<Context>()) );
+            builder.RegisterProxy<Handles<FamilyMemberToAdd>, AddNewFamilyMemberHandler>(interceptor);
+            builder.RegisterProxy<Handles<FindAllFamily>, FindAllFamilyHandler>(interceptor);
             new DB4OBootstrapper().run();
         }
     }
product/desktop.ui/solidware.financials.csproj
@@ -61,6 +61,7 @@
       <HintPath>..\..\thirdparty\autofac\Autofac.dll</HintPath>
     </Reference>
     <Reference Include="Castle.Core, Version=2.5.1.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL" />
+    <Reference Include="Db4objects.Db4o, Version=8.0.184.15484, Culture=neutral, PublicKeyToken=6199cd4f203aa8eb, processorArchitecture=MSIL" />
     <Reference Include="gorilla.infrastructure">
       <HintPath>..\..\thirdparty\commons\gorilla.infrastructure.dll</HintPath>
     </Reference>
product/infrastructure/CastleProxyFactory.cs
@@ -1,4 +1,7 @@
-using Castle.DynamicProxy;
+using System;
+using Castle.DynamicProxy;
+using gorilla.infrastructure.container;
+using gorilla.utility;
 
 namespace solidware.financials.infrastructure
 {
@@ -6,9 +9,56 @@ namespace solidware.financials.infrastructure
     {
         ProxyGenerator generator = new ProxyGenerator();
 
-        public Interface CreateProxyFor<Interface>(Interface target, params IInterceptor[] interceptors) where Interface : class
+        public Interface CreateProxyFor<Interface>(Interface target, params IInterceptor[] interceptors)
+            where Interface : class
         {
             return generator.CreateInterfaceProxyWithTarget(target, interceptors);
         }
     }
+
+    static public class Lazy
+    {
+        static public T load<T>() where T : class
+        {
+            return load(Resolve.the<T>);
+        }
+
+        static public T load<T>(Func<T> get_the_implementation) where T : class
+        {
+            return create_proxy_for<T>(create_interceptor_for(get_the_implementation));
+        }
+
+        static IInterceptor create_interceptor_for<T>(Func<T> get_the_implementation) where T : class
+        {
+            return new LazyLoadedInterceptor<T>(get_the_implementation.memorize());
+        }
+
+        static T create_proxy_for<T>(IInterceptor interceptor) where T : class
+        {
+            return new ProxyGenerator().CreateInterfaceProxyWithoutTarget<T>(interceptor);
+        }
+
+        class LazyLoadedInterceptor<T> : IInterceptor
+        {
+            readonly Func<T> get_the_implementation;
+
+            public LazyLoadedInterceptor(Func<T> get_the_implementation)
+            {
+                this.get_the_implementation = get_the_implementation;
+            }
+
+            public void Intercept(IInvocation invocation)
+            {
+                var method = invocation.GetConcreteMethodInvocationTarget();
+                if( null== method)
+                {
+                    invocation.ReturnValue = invocation.Method.Invoke(get_the_implementation(), invocation.Arguments);
+                }
+                else
+                {
+                    invocation.ReturnValue = method.Invoke(get_the_implementation(), invocation.Arguments);
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
product/service/orm/ConnectionFactory.cs
@@ -4,4 +4,4 @@
     {
         Connection Open();
     }
-}
\ No newline at end of file
+}
product/service/orm/DB40UnitOfWork.cs
@@ -1,21 +0,0 @@
-using System;
-
-namespace solidware.financials.service.orm
-{
-    public class DB40UnitOfWork : UnitOfWork
-    {
-        public DB40UnitOfWork(Connection connection)
-        {
-        }
-
-        public void Dispose()
-        {
-            throw new NotImplementedException();
-        }
-
-        public void commit()
-        {
-            throw new NotImplementedException();
-        }
-    }
-}
\ No newline at end of file
product/service/orm/DB40UnitOfWorkFactory.cs
@@ -20,7 +20,7 @@ namespace solidware.financials.service.orm
 
             var connection = factory.Open();
             context.add(key, connection);
-            return new DB4OUnitOfWork(connection);
+            return new DB4OUnitOfWork(connection, context);
         }
     }
 }
\ No newline at end of file
product/service/orm/DB4OConnection.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Ext;
+using Db4objects.Db4o.Query;
+
+namespace solidware.financials.service.orm
+{
+    public class DB4OConnection : Connection
+    {
+        readonly IEmbeddedObjectContainer session;
+
+        public DB4OConnection(IEmbeddedObjectContainer session)
+        {
+            this.session = session;
+        }
+
+        public void Dispose()
+        {
+            session.Dispose();
+        }
+
+        public void Activate(object obj, int depth)
+        {
+            session.Activate(obj, depth);
+        }
+
+        public bool Close()
+        {
+            return session.Close();
+        }
+
+        public void Commit()
+        {
+            session.Commit();
+        }
+
+        public void Deactivate(object obj, int depth)
+        {
+            session.Deactivate(obj, depth);
+        }
+
+        public void Delete(object obj)
+        {
+            session.Delete(obj);
+        }
+
+        public IExtObjectContainer Ext()
+        {
+            return session.Ext();
+        }
+
+        public IObjectSet QueryByExample(object template)
+        {
+            return session.QueryByExample(template);
+        }
+
+        public IQuery Query()
+        {
+            return session.Query();
+        }
+
+        public IObjectSet Query(Type clazz)
+        {
+            return session.Query(clazz);
+        }
+
+        public IObjectSet Query(Predicate predicate)
+        {
+            return session.Query(predicate);
+        }
+
+        public IObjectSet Query(Predicate predicate, IQueryComparator comparator)
+        {
+            return session.Query(predicate, comparator);
+        }
+
+        public IObjectSet Query(Predicate predicate, IComparer comparer)
+        {
+            return session.Query(predicate, comparer);
+        }
+
+        public void Rollback()
+        {
+            session.Rollback();
+        }
+
+        public void Store(object obj)
+        {
+            session.Store(obj);
+        }
+
+        public IList<Extent> Query<Extent>(Predicate<Extent> match)
+        {
+            return session.Query(match);
+        }
+
+        public IList<Extent> Query<Extent>(Predicate<Extent> match, IComparer<Extent> comparer)
+        {
+            return session.Query(match, comparer);
+        }
+
+        public IList<Extent> Query<Extent>(Predicate<Extent> match, Comparison<Extent> comparison)
+        {
+            return session.Query(match, comparison);
+        }
+
+        public IList<ElementType> Query<ElementType>(Type extent)
+        {
+            return session.Query<ElementType>(extent);
+        }
+
+        public IList<Extent> Query<Extent>()
+        {
+            return session.Query<Extent>();
+        }
+
+        public IList<Extent> Query<Extent>(IComparer<Extent> comparer)
+        {
+            return session.Query(comparer);
+        }
+
+        public void Backup(string path)
+        {
+            session.Backup(path);
+        }
+    }
+}
\ No newline at end of file
product/service/orm/DB4OConnectionFactory.cs
@@ -0,0 +1,39 @@
+using System;
+using System.IO;
+using Db4objects.Db4o;
+
+namespace solidware.financials.service.orm
+{
+    public class DB4OConnectionFactory : ConnectionFactory
+    {
+        public DB4OConnectionFactory()
+        {
+            database_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"mokhan.ca\momoney\default.db4o");
+        }
+
+        public Connection Open()
+        {
+            if (null == connection)
+            {
+                ensure_directories_exist();
+                connection = new DB4OConnection(Db4oEmbedded.OpenFile(database_path));
+            }
+            return connection;
+        }
+
+        void ensure_directories_exist()
+        {
+            var company_dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
+                                           @"mokhan.ca");
+            if (!Directory.Exists(company_dir))
+                Directory.CreateDirectory(company_dir);
+
+            var application_dir = Path.Combine(company_dir, "momoney");
+            if (!Directory.Exists(application_dir))
+                Directory.CreateDirectory(application_dir);
+        }
+
+        string database_path;
+        DB4OConnection connection;
+    }
+}
\ No newline at end of file
product/service/orm/DB4OPersonRepository.cs
@@ -1,16 +1,15 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using Db4objects.Db4o;
 using solidware.financials.service.domain;
 
 namespace solidware.financials.service.orm
 {
     public class DB4OPersonRepository : PersonRepository
     {
-        IObjectContainer session;
+        Connection session;
 
-        public DB4OPersonRepository(IObjectContainer session)
+        public DB4OPersonRepository(Connection session)
         {
             this.session = session;
         }
product/service/orm/DB4OUnitOfWork.cs
@@ -1,19 +1,17 @@
-namespace solidware.financials.service.orm
+using gorilla.utility;
+
+namespace solidware.financials.service.orm
 {
     public class DB4OUnitOfWork : UnitOfWork
     {
         readonly Connection connection;
+        readonly Context context;
         bool was_committed;
 
-        public DB4OUnitOfWork(Connection connection)
+        public DB4OUnitOfWork(Connection connection, Context context)
         {
             this.connection = connection;
-        }
-
-        public void Dispose()
-        {
-            if (!was_committed) connection.Rollback();
-            connection.Dispose();
+            this.context = context;
         }
 
         public void commit()
@@ -21,5 +19,12 @@
             connection.Commit();
             was_committed = true;
         }
+
+        public void Dispose()
+        {
+            if (!was_committed) connection.Rollback();
+            //connection.Dispose();
+            context.remove(new TypedKey<Connection>());
+        }
     }
 }
\ No newline at end of file
product/service/orm/EmptyUnitOfWork.cs
@@ -1,17 +1,13 @@
-using System;
-
-namespace solidware.financials.service.orm
+namespace solidware.financials.service.orm
 {
     public class EmptyUnitOfWork : UnitOfWork
     {
         public void Dispose()
         {
-            throw new NotImplementedException();
         }
 
         public void commit()
         {
-            throw new NotImplementedException();
         }
     }
 }
\ No newline at end of file
product/service/DB4OBootstrapper.cs
@@ -1,7 +1,6 @@
 using System;
 using System.Configuration;
 using System.IO;
-using Db4objects.Db4o;
 using gorilla.utility;
 using solidware.financials.service.orm;
 
@@ -9,8 +8,7 @@ namespace solidware.financials.service
 {
     public class DB4OBootstrapper : Command
     {
-        string database_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
-                                            @"mokhan.ca\momoney\default.db4o");
+        string database_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"mokhan.ca\momoney\default.db4o");
 
         Settings settings = new Settings(ConfigurationManager.AppSettings);
 
@@ -19,23 +17,10 @@ namespace solidware.financials.service
             if (settings.named<bool>("reset.db"))
                 if (File.Exists(database_path)) File.Delete(database_path);
 
-            ensure_directories_exist();
-
-            using (var database = Db4oEmbedded.OpenFile(database_path))
+            using (var database = new DB4OConnectionFactory().Open())
             {
                 database.Store(new LastOpened(Clock.now()));
             }
         }
-
-        void ensure_directories_exist()
-        {
-            var company_dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"mokhan.ca");
-            if (!Directory.Exists(company_dir))
-                Directory.CreateDirectory(company_dir);
-
-            var application_dir = Path.Combine(company_dir, "momoney");
-            if (!Directory.Exists(application_dir))
-                Directory.CreateDirectory(application_dir);
-        }
     }
 }
\ No newline at end of file
product/service/service.csproj
@@ -59,6 +59,8 @@
     <Compile Include="handlers\FindAllFamilyHandler.cs" />
     <Compile Include="orm\Connection.cs" />
     <Compile Include="orm\ConnectionFactory.cs" />
+    <Compile Include="orm\DB4OConnection.cs" />
+    <Compile Include="orm\DB4OConnectionFactory.cs" />
     <Compile Include="orm\DB4OUnitOfWork.cs" />
     <Compile Include="orm\DB40UnitOfWorkFactory.cs" />
     <Compile Include="orm\DB4OPersonRepository.cs" />
product/specs/unit/service/orm/DB4OUnitOfWorkSpecs.cs
@@ -1,3 +1,4 @@
+using gorilla.utility;
 using Machine.Specifications;
 using Rhino.Mocks;
 using solidware.financials.service.orm;
@@ -11,11 +12,13 @@ namespace specs.unit.service.orm
             Establish context = () =>
             {
                 session = Create.dependency<Connection>();
-                sut = new DB4OUnitOfWork(session);
+                the_context = Create.dependency<Context>();
+                sut = new DB4OUnitOfWork(session, the_context);
             };
 
             static protected DB4OUnitOfWork sut;
             static protected Connection session;
+            static Context the_context;
         }
 
         [Subject(typeof(DB4OUnitOfWork))]
product/specs/unit/service/orm/EmptyUnitOfWorkSpecs.cs
@@ -0,0 +1,25 @@
+using Machine.Specifications;
+using solidware.financials.service.orm;
+
+namespace specs.unit.service.orm
+{
+    public class EmptyUnitOfWorkSpecs
+    {
+        [Subject(typeof(EmptyUnitOfWork))]
+        public class When_disposing_an_empty_unit_of_work
+        {
+            It should_not_do_anything = () =>
+            {
+                new EmptyUnitOfWork().Dispose();
+            };
+        }
+        [Subject(typeof(EmptyUnitOfWork))]
+        public class When_committing_an_empty_unit_of_work
+        {
+            It should_not_do_anything = () =>
+            {
+                new EmptyUnitOfWork().commit();
+            };
+        }
+    }
+}
\ No newline at end of file
product/specs/specs.csproj
@@ -65,6 +65,7 @@
     <Compile Include="unit\infrastructure\ProxyFactorySpecs.cs" />
     <Compile Include="unit\service\orm\DB4OUnitOfWorkFactorySpecs.cs" />
     <Compile Include="unit\service\orm\DB4OUnitOfWorkSpecs.cs" />
+    <Compile Include="unit\service\orm\EmptyUnitOfWorkSpecs.cs" />
     <Compile Include="unit\service\orm\UnitOfWorkInterceptorSpecs.cs" />
     <Compile Include="unit\ui\InMemoryApplicationStateSpecs.cs" />
     <Compile Include="unit\ui\presenters\AddFamilyMemberPresenterSpecs.cs" />