Commit 3c90f65
Changed files (11)
product
desktop.ui
bootstrappers
service
specs
unit
service
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.