Commit 2e7be8b
Changed files (98)
build
product
Boot
boot
Modules
Presentation
Model
Messages
Presenters
Views
Winforms
Service
Infrastructure
Eventing
Threading
build/lib/app/gorilla/gorilla.commons.infrastructure.dll
Binary file
build/lib/app/gorilla/gorilla.commons.infrastructure.thirdparty.dll
Binary file
build/lib/app/gorilla/gorilla.commons.utility.dll
Binary file
product/Boot/boot/container/registration/proxy_configuration/NotifyProgressInterceptor.cs
@@ -0,0 +1,27 @@
+using Castle.Core.Interceptor;
+using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
+
+namespace MoMoney.boot.container.registration.proxy_configuration
+{
+ public interface INotifyProgressInterceptor : IInterceptor
+ {
+ }
+
+ public class NotifyProgressInterceptor : INotifyProgressInterceptor
+ {
+ readonly IEventAggregator broker;
+
+ public NotifyProgressInterceptor(IEventAggregator broker)
+ {
+ this.broker = broker;
+ }
+
+ public void Intercept(IInvocation invocation)
+ {
+ broker.publish(new StartedRunningCommand(invocation.TargetType.Name));
+ invocation.Proceed();
+ broker.publish(new FinishedRunningCommand(invocation.TargetType.Name));
+ }
+ }
+}
\ No newline at end of file
product/Boot/boot/container/registration/proxy_configuration/ServiceLayerConfiguration.cs
@@ -9,6 +9,7 @@ namespace MoMoney.boot.container.registration.proxy_configuration
public void configure(IProxyBuilder<T> item)
{
item.add_interceptor(Lazy.load<IUnitOfWorkInterceptor>()).intercept_all();
+ item.add_interceptor(Lazy.load<INotifyProgressInterceptor>()).intercept_all();
//item
// .add_interceptor(
product/Boot/boot/container/registration/proxy_configuration/UnitOfWorkInterceptor.cs
@@ -1,7 +1,7 @@
using Castle.Core.Interceptor;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Utility.Core;
using MoMoney.Service.Contracts.Infrastructure.Transactions;
+using MoMoney.Service.Infrastructure.Eventing;
using MoMoney.Service.Infrastructure.Transactions;
namespace MoMoney.boot.container.registration.proxy_configuration
product/Boot/boot/container/registration/wire_up_the_infrastructure_in_to_the.cs
@@ -2,13 +2,14 @@ using System.Collections;
using System.ComponentModel;
using System.Deployment.Application;
using Gorilla.Commons.Infrastructure;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Infrastructure.Registries;
using Gorilla.Commons.Infrastructure.Threading;
using Gorilla.Commons.Infrastructure.Transactions;
using Gorilla.Commons.Utility.Core;
using MoMoney.Presentation.Model.Projects;
using MoMoney.Presentation.Presenters.Commands;
+using MoMoney.Service.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Threading;
using MoMoney.Service.Infrastructure.Updating;
using MoMoney.Tasks.infrastructure.updating;
product/Boot/boot/container/registration/wire_up_the_services_in_to_the.cs
@@ -20,9 +20,6 @@ namespace MoMoney.boot.container.registration
public void run()
{
- registry.proxy<IGetTheCurrentCustomerQuery, ServiceLayerConfiguration<IGetTheCurrentCustomerQuery>>(
- () => new GetTheCurrentCustomerQuery(Lazy.load<IAccountHolderRepository>()));
-
wire_up_queries();
wire_up_the_commands();
}
@@ -39,6 +36,8 @@ namespace MoMoney.boot.container.registration
() =>
new GetAllIncomeQuery(Lazy.load<IIncomeRepository>(),
Lazy.load<IMapper<IIncome, IncomeInformationDTO>>()));
+ registry.proxy<IGetTheCurrentCustomerQuery, ServiceLayerConfiguration<IGetTheCurrentCustomerQuery>>(
+ () => new GetTheCurrentCustomerQuery(Lazy.load<IAccountHolderRepository>()));
}
void wire_up_the_commands()
product/Boot/boot/display_the_splash_screen.cs
@@ -1,5 +1,5 @@
using System;
-using MoMoney.Presentation.Presenters.Startup;
+using MoMoney.Presentation.Presenters;
using MoMoney.Utility.Core;
namespace MoMoney.boot
product/Boot/boot/global_error_handling.cs
@@ -1,11 +1,11 @@
using System;
using System.Windows.Forms;
using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Infrastructure.Logging;
using Gorilla.Commons.Utility.Core;
using Gorilla.Commons.Utility.Extensions;
using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.boot
{
product/Boot/boot/WindowsFormsApplication.cs
@@ -7,14 +7,14 @@ using System.Security.Principal;
using System.Threading;
using System.Windows.Forms;
using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Infrastructure.Logging;
using Gorilla.Commons.Infrastructure.Threading;
using Gorilla.Commons.Utility.Core;
using Gorilla.Commons.Utility.Extensions;
using MoMoney.boot.container;
using MoMoney.Presentation.Model.messages;
-using MoMoney.Presentation.Presenters.Startup;
+using MoMoney.Presentation.Presenters;
+using MoMoney.Service.Infrastructure.Eventing;
using MoMoney.windows.ui;
namespace MoMoney.boot
product/Boot/Modules/ApplicationMenuModule.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation.Model.Menu;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Presenters;
using MoMoney.Presentation.Presenters.Menu;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Modules/DatabaseModule.cs
@@ -1,5 +1,5 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.DataAccess;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Modules/GettingStartedModule.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Presenters;
using MoMoney.Presentation.Presenters.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Modules/GettingStartedModuleSpecs.cs
@@ -1,7 +1,7 @@
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Testing;
using MoMoney.Presentation.Presenters;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Modules/IApplicationMenuModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation;
using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Modules/IMainMenuModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation;
using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Modules/IToolbarModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation;
using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Modules/MainMenuModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Presenters;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Modules/ToolbarModule.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation.Model.Menu;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Presenters;
using MoMoney.Presentation.Presenters.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Modules
{
product/Boot/Boot.csproj
@@ -143,6 +143,7 @@
<Compile Include="boot\container\registration\proxy_configuration\InterceptingFilterFactorySpecs.cs" />
<Compile Include="boot\container\registration\proxy_configuration\InterceptingFilterSpecs.cs" />
<Compile Include="boot\container\registration\proxy_configuration\NoConfiguration.cs" />
+ <Compile Include="boot\container\registration\proxy_configuration\NotifyProgressInterceptor.cs" />
<Compile Include="boot\container\registration\proxy_configuration\SecuringProxy.cs" />
<Compile Include="boot\container\registration\proxy_configuration\SecuringProxySpecs.cs" />
<Compile Include="boot\container\registration\proxy_configuration\ServiceLayerConfiguration.cs" />
product/Presentation/Model/Menu/File/ExitCommand.cs
@@ -1,7 +1,7 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Utility.Core;
using MoMoney.Presentation.Core;
using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.Menu.File.Commands
{
product/Presentation/Model/Menu/File/ExitCommandSpecs.cs
@@ -1,8 +1,8 @@
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Testing;
using MoMoney.Presentation.Core;
using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.Menu.File.Commands
{
product/Presentation/Model/Menu/MenuItemBuilder.cs
@@ -1,10 +1,10 @@
using System;
using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Infrastructure.Threading;
using Gorilla.Commons.Utility.Core;
using MoMoney.Presentation.Winforms.Keyboard;
using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.Menu
{
product/Presentation/Model/Menu/ToolBarItemBuilder.cs
@@ -1,10 +1,10 @@
using System;
using System.Windows.Forms;
using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Infrastructure.Threading;
using Gorilla.Commons.Utility.Core;
using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.Menu
{
product/Presentation/Model/Messages/ClosingProjectEvent.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.messages
{
product/Presentation/Model/Messages/ClosingTheApplication.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.messages
{
product/Presentation/Model/Messages/FinishedRunningCommand.cs
@@ -0,0 +1,14 @@
+using MoMoney.Service.Infrastructure.Eventing;
+
+namespace MoMoney.Presentation.Model.messages
+{
+ public class FinishedRunningCommand : IEvent
+ {
+ public FinishedRunningCommand(object running_command)
+ {
+ completed_action = running_command;
+ }
+
+ public object completed_action { get; private set; }
+ }
+}
\ No newline at end of file
product/Presentation/Model/Messages/NewProjectOpened.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.messages
{
product/Presentation/Model/Messages/SavedChangesEvent.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.messages
{
product/Presentation/Model/Messages/StartedRunningCommand.cs
@@ -0,0 +1,14 @@
+using MoMoney.Service.Infrastructure.Eventing;
+
+namespace MoMoney.Presentation.Model.messages
+{
+ public class StartedRunningCommand : IEvent
+ {
+ public StartedRunningCommand(object running_command)
+ {
+ running_action = running_command;
+ }
+
+ public object running_action { get; private set; }
+ }
+}
\ No newline at end of file
product/Presentation/Model/Messages/UnhandledErrorOccurred.cs
@@ -1,5 +1,5 @@
using System;
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.messages
{
product/Presentation/Model/Messages/UnsavedChangesEvent.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Model.messages
{
product/Presentation/Model/Projects/ProjectController.cs
@@ -1,10 +1,10 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Infrastructure.FileSystem;
using Gorilla.Commons.Infrastructure.Logging;
using Gorilla.Commons.Utility.Core;
using Gorilla.Commons.Utility.Extensions;
using MoMoney.Presentation.Model.messages;
using MoMoney.Service.Contracts.Infrastructure;
+using MoMoney.Service.Infrastructure.Eventing;
using MoMoney.Service.Infrastructure.Transactions;
namespace MoMoney.Presentation.Model.Projects
product/Presentation/Model/Projects/ProjectControllerSpecs.cs
@@ -1,11 +1,11 @@
using System;
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Infrastructure.FileSystem;
using Gorilla.Commons.Testing;
using Gorilla.Commons.Utility.Extensions;
using MoMoney.Presentation.Model.messages;
using MoMoney.Service.Contracts.Infrastructure;
+using MoMoney.Service.Infrastructure.Eventing;
using MoMoney.Service.Infrastructure.Transactions;
namespace MoMoney.Presentation.Model.Projects
product/Presentation/Presenters/ApplicationShellPresenter.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation.Core;
using MoMoney.Presentation.Model.Menu.File.Commands;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Views;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Presenters/display_the_splash_screen.cs
@@ -1,6 +1,6 @@
using System;
-using Gorilla.Commons.Infrastructure.Threading;
using MoMoney.Presentation.Views.Startup;
+using MoMoney.Service.Infrastructure.Threading;
namespace MoMoney.Presentation.Presenters.Startup
{
product/Presentation/Presenters/GettingStartedPresenterSpecs.cs
@@ -1,7 +1,7 @@
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Testing;
using MoMoney.Presentation.Views.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Presenters/hide_the_splash_screen.cs
@@ -1,6 +1,6 @@
using System;
-using Gorilla.Commons.Infrastructure.Threading;
using MoMoney.Presentation.Views.Startup;
+using MoMoney.Service.Infrastructure.Threading;
namespace MoMoney.Presentation.Presenters.Startup
{
product/Presentation/Presenters/NotificationIconPresenter.cs
@@ -1,8 +1,8 @@
using System.Net.NetworkInformation;
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Views.Shell;
using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Presenters/NotificationIconPresenterSpecs.cs
@@ -1,8 +1,8 @@
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Testing;
using MoMoney.Presentation.Views.Shell;
using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Presenters/RestartCommand.cs
@@ -1,7 +1,7 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Utility.Core;
using MoMoney.Presentation.Core;
using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Commands
{
product/Presentation/Presenters/SplashScreenPresenter.cs
@@ -1,9 +1,11 @@
using Gorilla.Commons.Infrastructure.Threading;
+using MoMoney.Presentation.Presenters.Startup;
using MoMoney.Presentation.Views.Startup;
using MoMoney.Presentation.Winforms.Views;
+using MoMoney.Service.Infrastructure.Threading;
using MoMoney.Utility.Core;
-namespace MoMoney.Presentation.Presenters.Startup
+namespace MoMoney.Presentation.Presenters
{
public interface ISplashScreenPresenter : IDisposableCommand, ITimerClient
{
product/Presentation/Presenters/SplashScreenPresenterSpecs.cs
@@ -1,8 +1,8 @@
using System;
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Threading;
using Gorilla.Commons.Testing;
using MoMoney.Presentation.Views.Startup;
+using MoMoney.Service.Infrastructure.Threading;
namespace MoMoney.Presentation.Presenters.Startup
{
product/Presentation/Presenters/StatusBarPresenter.cs
@@ -1,16 +1,21 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using System;
using Gorilla.Commons.Utility;
using Gorilla.Commons.Utility.Extensions;
using MoMoney.Presentation.Model.messages;
-using MoMoney.Presentation.Views.Shell;
+using MoMoney.Presentation.Views;
using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Threading;
-namespace MoMoney.Presentation.Presenters.Shell
+namespace MoMoney.Presentation.Presenters
{
public interface IStatusBarPresenter : IModule,
IEventSubscriber<SavedChangesEvent>,
IEventSubscriber<NewProjectOpened>,
IEventSubscriber<ClosingTheApplication>,
+ IEventSubscriber<UnsavedChangesEvent>,
+ IEventSubscriber<StartedRunningCommand>,
+ IEventSubscriber<FinishedRunningCommand>,
IEventSubscriber<ClosingProjectEvent>
{
}
@@ -19,36 +24,57 @@ namespace MoMoney.Presentation.Presenters.Shell
{
readonly IStatusBarView view;
readonly IEventAggregator broker;
+ readonly ITimer timer;
- public StatusBarPresenter(IStatusBarView view, IEventAggregator broker)
+ public StatusBarPresenter(IStatusBarView view, IEventAggregator broker, ITimer timer)
{
this.view = view;
this.broker = broker;
+ this.timer = timer;
}
public void run()
{
broker.subscribe(this);
+ view.display(ApplicationIcons.blue_circle, "...");
}
public void notify(SavedChangesEvent message)
{
- view.display(ApplicationIcons.ApplicationReady, "Last Saved: {0}".formatted_using(Clock.now()));
+ view.display(ApplicationIcons.floppy_disk, "Last Saved: {0}".formatted_using(Clock.now()));
}
public void notify(NewProjectOpened message)
{
- view.display(ApplicationIcons.ApplicationReady, "Ready");
+ view.display(ApplicationIcons.green_circle, "Ready");
}
public void notify(ClosingTheApplication message)
{
- view.display(ApplicationIcons.Empty, "Good Bye!");
+ view.display(ApplicationIcons.hour_glass, "Good Bye!");
}
public void notify(ClosingProjectEvent message)
{
- view.display(ApplicationIcons.ApplicationReady, "Ready");
+ view.display(ApplicationIcons.grey_circle, "Closed");
+ }
+
+ public void notify(UnsavedChangesEvent message)
+ {
+ view.display(ApplicationIcons.red_circle, "Don't forget to save your work...");
+ }
+
+ public void notify(StartedRunningCommand message)
+ {
+ view.display(ApplicationIcons.hour_glass, "Running... {0}".formatted_using(message.running_action));
+ timer.start_notifying(view, new TimeSpan(1));
+ }
+
+ public void notify(FinishedRunningCommand message)
+ {
+ view.display(ApplicationIcons.green_circle, "Finished... {0}".formatted_using(message.completed_action));
+ timer.stop_notifying(view);
+ view.reset_progress_bar();
}
}
}
\ No newline at end of file
product/Presentation/Presenters/StatusBarPresenterSpecs.cs
@@ -1,17 +1,17 @@
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Testing;
using MoMoney.Presentation.Model.messages;
-using MoMoney.Presentation.Views.Shell;
+using MoMoney.Presentation.Views;
using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
-namespace MoMoney.Presentation.Presenters.Shell
+namespace MoMoney.Presentation.Presenters
{
[Concern(typeof (StatusBarPresenter))]
public class when_initializing_the_status_bar : concerns_for<IStatusBarPresenter, StatusBarPresenter>
{
it should_display_a_ready_message =
- () => view.was_told_to(v => v.display(ApplicationIcons.ApplicationReady, "Ready"));
+ () => view.was_told_to(v => v.display(ApplicationIcons.green_circle, "Ready"));
context c = () =>
{
@@ -21,11 +21,6 @@ namespace MoMoney.Presentation.Presenters.Shell
because b = () => sut.notify(new NewProjectOpened(""));
- //public override IStatusBarPresenter create_sut()
- //{
- // return new StatusBarPresenter(view, broker);
- //}
-
static IStatusBarView view;
static IEventAggregator broker;
}
product/Presentation/Presenters/TaskTrayPresenter.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Views.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Presenters/TitleBarPresenter.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Infrastructure.Logging;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Model.Projects;
using MoMoney.Presentation.Views;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Presenters/TitleBarPresenterSpecs.cs
@@ -1,9 +1,9 @@
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Testing;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Model.Projects;
using MoMoney.Presentation.Views;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Presenters/UnhandledErrorPresenter.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
using MoMoney.Presentation.Core;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Presenters.Commands;
using MoMoney.Presentation.Views.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Presenters/UnhandledErrorPresenterSpecs.cs
@@ -1,9 +1,9 @@
using System;
using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
using Gorilla.Commons.Testing;
using MoMoney.Presentation.Model.messages;
using MoMoney.Presentation.Views.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
namespace MoMoney.Presentation.Presenters.Shell
{
product/Presentation/Views/IStatusBarView.cs
@@ -1,9 +1,11 @@
+using Gorilla.Commons.Infrastructure.Threading;
using MoMoney.Presentation.Winforms.Resources;
-namespace MoMoney.Presentation.Views.Shell
+namespace MoMoney.Presentation.Views
{
- public interface IStatusBarView
+ public interface IStatusBarView : ITimerClient
{
void display(HybridIcon icon_to_display, string text_to_display);
+ void reset_progress_bar();
}
}
\ No newline at end of file
product/Presentation/Winforms/Resources/ApplicationIcons.cs
@@ -9,7 +9,6 @@ namespace MoMoney.Presentation.Winforms.Resources
static public readonly ApplicationIcon Application = new ApplicationIcon("mokhan.ico", x => add(x));
static public readonly ApplicationIcon FileExplorer = new ApplicationIcon("binoculars.ico", x => add(x));
- static public readonly HybridIcon ApplicationReady = new HybridIcon("circle_green.ico", x => add(x));
static public readonly ApplicationIcon AddIncome = new ApplicationIcon("generic_document.ico", x => add(x));
static public readonly HybridIcon NewProject = new HybridIcon("generic_document.ico", x => add(x));
static public readonly HybridIcon OpenProject = new HybridIcon("foldergreen.ico", x => add(x));
@@ -28,6 +27,17 @@ namespace MoMoney.Presentation.Winforms.Resources
static public readonly HybridIcon ViewAllIncome = new HybridIcon("search.ico", x => add(x));
static public readonly HybridIcon AddBillPayment = new HybridIcon("plus__orange.ico", x => add(x));
static public readonly HybridIcon ViewAllBillPayments = new HybridIcon("search.ico", x => add(x));
+ static public readonly HybridIcon Home = new HybridIcon("home.ico", x => add(x));
+
+ static public readonly HybridIcon hour_glass = new HybridIcon("hourglass.ico", x => add(x));
+ static public readonly HybridIcon green_circle = new HybridIcon("circle_green.ico", x => add(x));
+ static public readonly HybridIcon blue_circle = new HybridIcon("circle_blue.ico", x => add(x));
+ static public readonly HybridIcon grey_circle = new HybridIcon("circle_grey.ico", x => add(x));
+ static public readonly HybridIcon orange_circle = new HybridIcon("circle_orange.ico", x => add(x));
+ static public readonly HybridIcon red_circle = new HybridIcon("circle_red.ico", x => add(x));
+ static public readonly HybridIcon yellow_circle = new HybridIcon("circle_yellow.ico", x => add(x));
+
+ static public readonly HybridIcon floppy_disk = new HybridIcon("floppydisk.ico", x => add(x));
static public IEnumerable<ApplicationIcon> all()
{
product/Presentation/Winforms/Views/AddBillPaymentView.cs
@@ -7,6 +7,7 @@ using MoMoney.Presentation.Views.billing;
using MoMoney.Presentation.Views.Core;
using MoMoney.Presentation.Winforms.Helpers;
using MoMoney.Presentation.Winforms.Krypton;
+using MoMoney.Presentation.Winforms.Resources;
namespace MoMoney.Presentation.Winforms.Views
{
@@ -18,7 +19,8 @@ namespace MoMoney.Presentation.Winforms.Views
public AddBillPaymentView()
{
InitializeComponent();
- titled("Add Bill Payment");
+ titled("Add Bill Payment")
+ .icon(ApplicationIcons.AddBillPayment);
ux_submit_button.Click += (sender, e) => submit_clicked(e);
companies_list = ux_company_names.create_for<CompanyDTO>();
}
product/Presentation/Winforms/Views/AddCompanyView.cs
@@ -20,7 +20,8 @@ namespace MoMoney.Presentation.Winforms.Views
public AddCompanyView()
{
InitializeComponent();
- titled("Add A Company");
+ titled("Add A Company")
+ .icon(ApplicationIcons.AddCompany);
dto = new RegisterNewCompany();
listView1.View = View.LargeIcon;
product/Presentation/Winforms/Views/AddCompanyView.Designer.cs
@@ -30,34 +30,26 @@ namespace MoMoney.Presentation.Winforms.Views
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddCompanyView));
this.kryptonHeaderGroup1 = new ComponentFactory.Krypton.Toolkit.KryptonHeaderGroup();
+ this.ux_companys_listing = new ComponentFactory.Krypton.Toolkit.KryptonDataGridView();
+ this.kryptonSplitContainer2 = new ComponentFactory.Krypton.Toolkit.KryptonSplitContainer();
+ this.kryptonGroup1 = new ComponentFactory.Krypton.Toolkit.KryptonGroup();
+ this.kryptonGroup2 = new ComponentFactory.Krypton.Toolkit.KryptonGroup();
this.kryptonSplitContainer1 = new ComponentFactory.Krypton.Toolkit.KryptonSplitContainer();
this.listView1 = new System.Windows.Forms.ListView();
this.ux_submit_button = new ComponentFactory.Krypton.Toolkit.KryptonButton();
- this.kryptonLabel1 = new ComponentFactory.Krypton.Toolkit.KryptonLabel();
this.ux_company_name = new ComponentFactory.Krypton.Toolkit.KryptonTextBox();
this.ux_cancel_button = new System.Windows.Forms.Button();
- this.kryptonSplitContainer2 = new ComponentFactory.Krypton.Toolkit.KryptonSplitContainer();
- this.kryptonHeader1 = new ComponentFactory.Krypton.Toolkit.KryptonHeader();
- this.ux_companys_listing = new ComponentFactory.Krypton.Toolkit.KryptonDataGridView();
- this.kryptonGroup1 = new ComponentFactory.Krypton.Toolkit.KryptonGroup();
- this.kryptonGroup2 = new ComponentFactory.Krypton.Toolkit.KryptonGroup();
+ this.kryptonLabel1 = new ComponentFactory.Krypton.Toolkit.KryptonLabel();
((System.ComponentModel.ISupportInitialize)(this.kryptonHeaderGroup1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.kryptonHeaderGroup1.Panel)).BeginInit();
this.kryptonHeaderGroup1.Panel.SuspendLayout();
this.kryptonHeaderGroup1.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel1)).BeginInit();
- this.kryptonSplitContainer1.Panel1.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel2)).BeginInit();
- this.kryptonSplitContainer1.Panel2.SuspendLayout();
- this.kryptonSplitContainer1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2.Panel1)).BeginInit();
- this.kryptonSplitContainer2.Panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2.Panel2)).BeginInit();
this.kryptonSplitContainer2.Panel2.SuspendLayout();
this.kryptonSplitContainer2.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.kryptonGroup1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.kryptonGroup1.Panel)).BeginInit();
this.kryptonGroup1.Panel.SuspendLayout();
@@ -66,19 +58,26 @@ namespace MoMoney.Presentation.Winforms.Views
((System.ComponentModel.ISupportInitialize)(this.kryptonGroup2.Panel)).BeginInit();
this.kryptonGroup2.Panel.SuspendLayout();
this.kryptonGroup2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel1)).BeginInit();
+ this.kryptonSplitContainer1.Panel1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel2)).BeginInit();
+ this.kryptonSplitContainer1.Panel2.SuspendLayout();
+ this.kryptonSplitContainer1.SuspendLayout();
this.SuspendLayout();
//
// kryptonHeaderGroup1
//
this.kryptonHeaderGroup1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.kryptonHeaderGroup1.GroupBackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.FormMain;
this.kryptonHeaderGroup1.Location = new System.Drawing.Point(0, 0);
- this.kryptonHeaderGroup1.Margin = new System.Windows.Forms.Padding(4);
this.kryptonHeaderGroup1.Name = "kryptonHeaderGroup1";
+ this.kryptonHeaderGroup1.PaletteMode = ComponentFactory.Krypton.Toolkit.PaletteMode.SparkleBlue;
//
// kryptonHeaderGroup1.Panel
//
this.kryptonHeaderGroup1.Panel.Controls.Add(this.kryptonSplitContainer1);
- this.kryptonHeaderGroup1.Size = new System.Drawing.Size(1037, 876);
+ this.kryptonHeaderGroup1.Size = new System.Drawing.Size(778, 712);
this.kryptonHeaderGroup1.TabIndex = 0;
this.kryptonHeaderGroup1.Text = "Add Company";
this.kryptonHeaderGroup1.ValuesPrimary.Description = "";
@@ -88,42 +87,102 @@ namespace MoMoney.Presentation.Winforms.Views
this.kryptonHeaderGroup1.ValuesSecondary.Heading = "Description";
this.kryptonHeaderGroup1.ValuesSecondary.Image = null;
//
+ // ux_companys_listing
+ //
+ this.ux_companys_listing.AllowUserToAddRows = false;
+ this.ux_companys_listing.AllowUserToDeleteRows = false;
+ this.ux_companys_listing.AllowUserToOrderColumns = true;
+ this.ux_companys_listing.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ this.ux_companys_listing.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ux_companys_listing.Location = new System.Drawing.Point(0, 0);
+ this.ux_companys_listing.Name = "ux_companys_listing";
+ this.ux_companys_listing.ReadOnly = true;
+ this.ux_companys_listing.Size = new System.Drawing.Size(201, 584);
+ this.ux_companys_listing.StateCommon.BackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.GridBackgroundList;
+ this.ux_companys_listing.TabIndex = 25;
+ //
+ // kryptonSplitContainer2
+ //
+ this.kryptonSplitContainer2.Cursor = System.Windows.Forms.Cursors.Default;
+ this.kryptonSplitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.kryptonSplitContainer2.Location = new System.Drawing.Point(0, 0);
+ this.kryptonSplitContainer2.Name = "kryptonSplitContainer2";
+ this.kryptonSplitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // kryptonSplitContainer2.Panel1
+ //
+ this.kryptonSplitContainer2.Panel1.PanelBackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.FormCustom1;
+ //
+ // kryptonSplitContainer2.Panel2
+ //
+ this.kryptonSplitContainer2.Panel2.Controls.Add(this.ux_companys_listing);
+ this.kryptonSplitContainer2.SeparatorStyle = ComponentFactory.Krypton.Toolkit.SeparatorStyle.HighProfile;
+ this.kryptonSplitContainer2.Size = new System.Drawing.Size(201, 655);
+ this.kryptonSplitContainer2.SplitterDistance = 66;
+ this.kryptonSplitContainer2.TabIndex = 26;
+ //
+ // kryptonGroup1
+ //
+ this.kryptonGroup1.Location = new System.Drawing.Point(8, 3);
+ this.kryptonGroup1.Margin = new System.Windows.Forms.Padding(2);
+ this.kryptonGroup1.Name = "kryptonGroup1";
+ //
+ // kryptonGroup1.Panel
+ //
+ this.kryptonGroup1.Panel.Controls.Add(this.kryptonLabel1);
+ this.kryptonGroup1.Panel.Controls.Add(this.ux_cancel_button);
+ this.kryptonGroup1.Panel.Controls.Add(this.ux_company_name);
+ this.kryptonGroup1.Panel.Controls.Add(this.ux_submit_button);
+ this.kryptonGroup1.Size = new System.Drawing.Size(532, 110);
+ this.kryptonGroup1.TabIndex = 23;
+ //
+ // kryptonGroup2
+ //
+ this.kryptonGroup2.Location = new System.Drawing.Point(9, 141);
+ this.kryptonGroup2.Margin = new System.Windows.Forms.Padding(2);
+ this.kryptonGroup2.Name = "kryptonGroup2";
+ //
+ // kryptonGroup2.Panel
+ //
+ this.kryptonGroup2.Panel.Controls.Add(this.listView1);
+ this.kryptonGroup2.Size = new System.Drawing.Size(552, 273);
+ this.kryptonGroup2.TabIndex = 24;
+ //
// kryptonSplitContainer1
//
this.kryptonSplitContainer1.Cursor = System.Windows.Forms.Cursors.Default;
this.kryptonSplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.kryptonSplitContainer1.Location = new System.Drawing.Point(0, 0);
- this.kryptonSplitContainer1.Margin = new System.Windows.Forms.Padding(4);
this.kryptonSplitContainer1.Name = "kryptonSplitContainer1";
//
// kryptonSplitContainer1.Panel1
//
this.kryptonSplitContainer1.Panel1.Controls.Add(this.kryptonGroup2);
this.kryptonSplitContainer1.Panel1.Controls.Add(this.kryptonGroup1);
+ this.kryptonSplitContainer1.Panel1.PanelBackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.FormMain;
//
// kryptonSplitContainer1.Panel2
//
this.kryptonSplitContainer1.Panel2.Controls.Add(this.kryptonSplitContainer2);
this.kryptonSplitContainer1.SeparatorStyle = ComponentFactory.Krypton.Toolkit.SeparatorStyle.HighProfile;
- this.kryptonSplitContainer1.Size = new System.Drawing.Size(1035, 813);
- this.kryptonSplitContainer1.SplitterDistance = 764;
+ this.kryptonSplitContainer1.Size = new System.Drawing.Size(776, 655);
+ this.kryptonSplitContainer1.SplitterDistance = 570;
this.kryptonSplitContainer1.TabIndex = 25;
//
// listView1
//
- this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.listView1.Location = new System.Drawing.Point(0, 0);
+ this.listView1.Location = new System.Drawing.Point(2, 34);
+ this.listView1.Margin = new System.Windows.Forms.Padding(2);
this.listView1.Name = "listView1";
- this.listView1.Size = new System.Drawing.Size(734, 334);
+ this.listView1.Size = new System.Drawing.Size(550, 182);
this.listView1.TabIndex = 21;
this.listView1.UseCompatibleStateImageBehavior = false;
//
// ux_submit_button
//
- this.ux_submit_button.Location = new System.Drawing.Point(147, 77);
- this.ux_submit_button.Margin = new System.Windows.Forms.Padding(4);
+ this.ux_submit_button.Location = new System.Drawing.Point(110, 63);
this.ux_submit_button.Name = "ux_submit_button";
- this.ux_submit_button.Size = new System.Drawing.Size(120, 31);
+ this.ux_submit_button.Size = new System.Drawing.Size(90, 25);
this.ux_submit_button.TabIndex = 2;
this.ux_submit_button.Text = "&Submit";
this.ux_submit_button.Values.ExtraText = "";
@@ -133,119 +192,44 @@ namespace MoMoney.Presentation.Winforms.Views
this.ux_submit_button.Values.ImageStates.ImageCheckedTracking = null;
this.ux_submit_button.Values.Text = "&Submit";
//
- // kryptonLabel1
- //
- this.kryptonLabel1.Location = new System.Drawing.Point(15, 26);
- this.kryptonLabel1.Margin = new System.Windows.Forms.Padding(4);
- this.kryptonLabel1.Name = "kryptonLabel1";
- this.kryptonLabel1.Size = new System.Drawing.Size(125, 24);
- this.kryptonLabel1.TabIndex = 20;
- this.kryptonLabel1.Text = "Company Name:";
- this.kryptonLabel1.Values.ExtraText = "";
- this.kryptonLabel1.Values.Image = null;
- this.kryptonLabel1.Values.Text = "Company Name:";
- //
// ux_company_name
//
- this.ux_company_name.Location = new System.Drawing.Point(147, 26);
- this.ux_company_name.Margin = new System.Windows.Forms.Padding(4);
+ this.ux_company_name.Location = new System.Drawing.Point(110, 21);
this.ux_company_name.Name = "ux_company_name";
- this.ux_company_name.Size = new System.Drawing.Size(547, 24);
+ this.ux_company_name.Size = new System.Drawing.Size(410, 20);
this.ux_company_name.TabIndex = 1;
//
// ux_cancel_button
//
this.ux_cancel_button.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.ux_cancel_button.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.ux_cancel_button.Location = new System.Drawing.Point(275, 77);
- this.ux_cancel_button.Margin = new System.Windows.Forms.Padding(4);
+ this.ux_cancel_button.Location = new System.Drawing.Point(206, 63);
this.ux_cancel_button.Name = "ux_cancel_button";
- this.ux_cancel_button.Size = new System.Drawing.Size(76, 31);
+ this.ux_cancel_button.Size = new System.Drawing.Size(57, 25);
this.ux_cancel_button.TabIndex = 3;
this.ux_cancel_button.Text = "Cancel";
this.ux_cancel_button.UseVisualStyleBackColor = true;
//
- // kryptonSplitContainer2
- //
- this.kryptonSplitContainer2.Cursor = System.Windows.Forms.Cursors.Default;
- this.kryptonSplitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
- this.kryptonSplitContainer2.Location = new System.Drawing.Point(0, 0);
- this.kryptonSplitContainer2.Margin = new System.Windows.Forms.Padding(4);
- this.kryptonSplitContainer2.Name = "kryptonSplitContainer2";
- this.kryptonSplitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
- //
- // kryptonSplitContainer2.Panel1
- //
- this.kryptonSplitContainer2.Panel1.Controls.Add(this.kryptonHeader1);
- //
- // kryptonSplitContainer2.Panel2
- //
- this.kryptonSplitContainer2.Panel2.Controls.Add(this.ux_companys_listing);
- this.kryptonSplitContainer2.SeparatorStyle = ComponentFactory.Krypton.Toolkit.SeparatorStyle.HighProfile;
- this.kryptonSplitContainer2.Size = new System.Drawing.Size(266, 813);
- this.kryptonSplitContainer2.SplitterDistance = 46;
- this.kryptonSplitContainer2.TabIndex = 26;
- //
- // kryptonHeader1
- //
- this.kryptonHeader1.Location = new System.Drawing.Point(4, 4);
- this.kryptonHeader1.Margin = new System.Windows.Forms.Padding(4);
- this.kryptonHeader1.Name = "kryptonHeader1";
- this.kryptonHeader1.Size = new System.Drawing.Size(144, 37);
- this.kryptonHeader1.TabIndex = 25;
- this.kryptonHeader1.Text = "Companys";
- this.kryptonHeader1.Values.Description = "";
- this.kryptonHeader1.Values.Heading = "Companys";
- this.kryptonHeader1.Values.Image = ((System.Drawing.Image)(resources.GetObject("kryptonHeader1.Values.Image")));
- //
- // ux_companys_listing
- //
- this.ux_companys_listing.AllowUserToAddRows = false;
- this.ux_companys_listing.AllowUserToDeleteRows = false;
- this.ux_companys_listing.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
- this.ux_companys_listing.Dock = System.Windows.Forms.DockStyle.Fill;
- this.ux_companys_listing.Location = new System.Drawing.Point(0, 0);
- this.ux_companys_listing.Margin = new System.Windows.Forms.Padding(4);
- this.ux_companys_listing.Name = "ux_companys_listing";
- this.ux_companys_listing.ReadOnly = true;
- this.ux_companys_listing.Size = new System.Drawing.Size(266, 762);
- this.ux_companys_listing.StateCommon.BackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.GridBackgroundList;
- this.ux_companys_listing.TabIndex = 25;
- //
- // kryptonGroup1
- //
- this.kryptonGroup1.Location = new System.Drawing.Point(11, 4);
- this.kryptonGroup1.Name = "kryptonGroup1";
- //
- // kryptonGroup1.Panel
- //
- this.kryptonGroup1.Panel.Controls.Add(this.kryptonLabel1);
- this.kryptonGroup1.Panel.Controls.Add(this.ux_cancel_button);
- this.kryptonGroup1.Panel.Controls.Add(this.ux_company_name);
- this.kryptonGroup1.Panel.Controls.Add(this.ux_submit_button);
- this.kryptonGroup1.Size = new System.Drawing.Size(710, 135);
- this.kryptonGroup1.TabIndex = 23;
- //
- // kryptonGroup2
- //
- this.kryptonGroup2.Location = new System.Drawing.Point(12, 173);
- this.kryptonGroup2.Name = "kryptonGroup2";
- //
- // kryptonGroup2.Panel
+ // kryptonLabel1
//
- this.kryptonGroup2.Panel.Controls.Add(this.listView1);
- this.kryptonGroup2.Size = new System.Drawing.Size(736, 336);
- this.kryptonGroup2.TabIndex = 24;
+ this.kryptonLabel1.Location = new System.Drawing.Point(11, 21);
+ this.kryptonLabel1.Name = "kryptonLabel1";
+ this.kryptonLabel1.Size = new System.Drawing.Size(101, 20);
+ this.kryptonLabel1.TabIndex = 20;
+ this.kryptonLabel1.Text = "Company Name:";
+ this.kryptonLabel1.Values.ExtraText = "";
+ this.kryptonLabel1.Values.Image = null;
+ this.kryptonLabel1.Values.Text = "Company Name:";
//
// AddCompanyView
//
this.AcceptButton = this.ux_submit_button;
- this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.ux_cancel_button;
- this.ClientSize = new System.Drawing.Size(1037, 876);
+ this.ClientSize = new System.Drawing.Size(778, 712);
this.Controls.Add(this.kryptonHeaderGroup1);
- this.Margin = new System.Windows.Forms.Padding(4);
+ this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Name = "AddCompanyView";
this.TabText = "AddExpenseView";
this.Text = "Add A New Bill";
@@ -253,20 +237,12 @@ namespace MoMoney.Presentation.Winforms.Views
this.kryptonHeaderGroup1.Panel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.kryptonHeaderGroup1)).EndInit();
this.kryptonHeaderGroup1.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel1)).EndInit();
- this.kryptonSplitContainer1.Panel1.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel2)).EndInit();
- this.kryptonSplitContainer1.Panel2.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1)).EndInit();
- this.kryptonSplitContainer1.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2.Panel1)).EndInit();
- this.kryptonSplitContainer2.Panel1.ResumeLayout(false);
- this.kryptonSplitContainer2.Panel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2.Panel2)).EndInit();
this.kryptonSplitContainer2.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2)).EndInit();
this.kryptonSplitContainer2.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.kryptonGroup1.Panel)).EndInit();
this.kryptonGroup1.Panel.ResumeLayout(false);
this.kryptonGroup1.Panel.PerformLayout();
@@ -276,6 +252,12 @@ namespace MoMoney.Presentation.Winforms.Views
this.kryptonGroup2.Panel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.kryptonGroup2)).EndInit();
this.kryptonGroup2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel1)).EndInit();
+ this.kryptonSplitContainer1.Panel1.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel2)).EndInit();
+ this.kryptonSplitContainer1.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1)).EndInit();
+ this.kryptonSplitContainer1.ResumeLayout(false);
this.ResumeLayout(false);
}
@@ -283,17 +265,16 @@ namespace MoMoney.Presentation.Winforms.Views
#endregion
private ComponentFactory.Krypton.Toolkit.KryptonHeaderGroup kryptonHeaderGroup1;
- private ComponentFactory.Krypton.Toolkit.KryptonTextBox ux_company_name;
- private System.Windows.Forms.Button ux_cancel_button;
+ private ComponentFactory.Krypton.Toolkit.KryptonDataGridView ux_companys_listing;
private ComponentFactory.Krypton.Toolkit.KryptonSplitContainer kryptonSplitContainer1;
+ private ComponentFactory.Krypton.Toolkit.KryptonGroup kryptonGroup2;
+ private System.Windows.Forms.ListView listView1;
+ private ComponentFactory.Krypton.Toolkit.KryptonGroup kryptonGroup1;
private ComponentFactory.Krypton.Toolkit.KryptonLabel kryptonLabel1;
- private ComponentFactory.Krypton.Toolkit.KryptonHeader kryptonHeader1;
+ private System.Windows.Forms.Button ux_cancel_button;
+ private ComponentFactory.Krypton.Toolkit.KryptonTextBox ux_company_name;
private ComponentFactory.Krypton.Toolkit.KryptonButton ux_submit_button;
private ComponentFactory.Krypton.Toolkit.KryptonSplitContainer kryptonSplitContainer2;
- private ComponentFactory.Krypton.Toolkit.KryptonDataGridView ux_companys_listing;
- private System.Windows.Forms.ListView listView1;
- private ComponentFactory.Krypton.Toolkit.KryptonGroup kryptonGroup1;
- private ComponentFactory.Krypton.Toolkit.KryptonGroup kryptonGroup2;
}
}
\ No newline at end of file
product/Presentation/Winforms/Views/AddCompanyView.resx
@@ -118,29 +118,10 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
- <data name="kryptonHeader1.Values.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>
- iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
- JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsOAAALDgFAvuFBAAAC6UlE
- QVQ4T43TW0jTYRgGcC+MKEQziLwQPGTqWqY25zw1/6bzsDmdeUxzMy1dmytrrU2nQWrmIZVCo4zAEgm7
- SKSg0iLIs66ssDLdPG2armxFdpgOn6aQJCX63n7v87t4Xj4TkzUmVJK7US5y5hdJ7X+Uynfqz56yFayV
- +ee9ppzAaKc3ND3ekJ0mFlYFxGn2lgUS+6Zrxc4oydmhPc3fTiwuN9yWo7PRHcrOSHBS0rEqkC+2rXpU
- 7wpVuw/6n9BQW7EL5bl2aKl3g7I9CKKTKfAMSRx19adu+S8ilzAnFA+Z6GtmYriTgaFWH2OQgKqLjYH2
- WMgkHBTlErhU6I+6q9E4KXCLXwEVFoiIcG7W9ZAkIVqaEqDsYEDVG4zRF0yMPA+C9j0XU2+5RnSxDxp4
- PF/DElBwxs6zppS0UH+ZhMJsV2Sk++BdOxOafrox7IWxPhLUgxdQUcZGdVUMxt6W4eNwJXyZiZNLQL7Y
- Xj3U5oPB1n0Y6QqF5mUk1K8DMdpHNiJO0I5wERAcBjqbp2AlZyoOZ4lxNIMFd3pYhYn0mC23ocoFqo4g
- DHVEYEQRBc0rBr5OlUCnToFWZYOpcRGcyC4aMsXDwo/JtTmYLmXTwxNSHXdTCBOZ0OFx1/0ADPfEQtkd
- ZyzMD8r+ahwRRqH5AQu6CSvMareht20Lys9bzJWcM3tTWWy6d7k8+XGaXt2fB+1gnrH5EOhU6UhOJrDH
- m4nGJgZmP23Fd5059LNmmPlgCZ02A34hjNpl4FAqP4kTF4ebdTl4dE+GG1fYcCRTIeKbl77ptcK3zxbQ
- f98Ew/wG6KY3Y1xzB1RGYuuK86WdyBZys87eCjcWRGfFw9qGdLGwIMKj+ykVhl+ZmNeb4cuMKWCoRqYk
- BRQ6q2xd/0EklaLhLg8fpxsw9zMHz54SoPgfWHD3DaCsC+AJxFl8WfFkkiAXrBgOiOD9ILl5PVxX+M9S
- eHwqOZCTUBwYnawgu9MGrHeQHf4GfgNkMpj0S8vAHQAAAABJRU5ErkJggg==
-</value>
- </data>
<data name="kryptonHeaderGroup1.ValuesPrimary.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
- JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsOAAALDgFAvuFBAAAC6UlE
+ JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsMAAALDAE/QCLIAAAC6UlE
QVQ4T43TW0jTYRgGcC+MKEQziLwQPGTqWqY25zw1/6bzsDmdeUxzMy1dmytrrU2nQWrmIZVCo4zAEgm7
SKSg0iLIs66ssDLdPG2armxFdpgOn6aQJCX63n7v87t4Xj4TkzUmVJK7US5y5hdJ7X+Uynfqz56yFayV
+ee9ppzAaKc3ND3ekJ0mFlYFxGn2lgUS+6Zrxc4oydmhPc3fTiwuN9yWo7PRHcrOSHBS0rEqkC+2rXpU
product/Presentation/Winforms/Views/AddNewIncomeView.cs
@@ -7,6 +7,7 @@ using MoMoney.Presentation.Views.Core;
using MoMoney.Presentation.Views.income;
using MoMoney.Presentation.Winforms.Helpers;
using MoMoney.Presentation.Winforms.Krypton;
+using MoMoney.Presentation.Winforms.Resources;
namespace MoMoney.Presentation.Winforms.Views
{
@@ -18,7 +19,8 @@ namespace MoMoney.Presentation.Winforms.Views
public AddNewIncomeView()
{
InitializeComponent();
- titled("Add Income");
+ titled("Add Income")
+ .icon(ApplicationIcons.AddNewIncome);
ux_submit_button.Click += (sender, e) => submit_button(e);
companies_list = ux_companys.create_for<CompanyDTO>();
product/Presentation/Winforms/Views/CheckForUpdatesView.Designer.cs
@@ -43,40 +43,36 @@ namespace MoMoney.Presentation.Winforms.Views
// label3
//
this.label3.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.label3.Location = new System.Drawing.Point(12, 211);
- this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.label3.Location = new System.Drawing.Point(9, 171);
this.label3.Name = "label3";
- this.label3.Size = new System.Drawing.Size(364, 2);
+ this.label3.Size = new System.Drawing.Size(273, 2);
this.label3.TabIndex = 15;
this.label3.Text = " " +
- " ";
+ " ";
//
// label2
//
this.label2.AutoSize = true;
- this.label2.Location = new System.Drawing.Point(178, 66);
- this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.label2.Location = new System.Drawing.Point(134, 54);
this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(177, 17);
+ this.label2.Size = new System.Drawing.Size(136, 13);
this.label2.TabIndex = 14;
this.label2.Text = "What would you like to do?";
//
// ux_current_version
//
this.ux_current_version.AutoSize = true;
- this.ux_current_version.Location = new System.Drawing.Point(178, 13);
- this.ux_current_version.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.ux_current_version.Location = new System.Drawing.Point(134, 11);
this.ux_current_version.Name = "ux_current_version";
- this.ux_current_version.Size = new System.Drawing.Size(59, 17);
+ this.ux_current_version.Size = new System.Drawing.Size(44, 13);
this.ux_current_version.TabIndex = 13;
this.ux_current_version.Text = "Current:";
//
// ux_image
//
- this.ux_image.Location = new System.Drawing.Point(13, 13);
- this.ux_image.Margin = new System.Windows.Forms.Padding(4);
+ this.ux_image.Location = new System.Drawing.Point(10, 11);
this.ux_image.Name = "ux_image";
- this.ux_image.Size = new System.Drawing.Size(153, 105);
+ this.ux_image.Size = new System.Drawing.Size(115, 85);
this.ux_image.TabIndex = 12;
this.ux_image.TabStop = false;
//
@@ -84,10 +80,9 @@ namespace MoMoney.Presentation.Winforms.Views
//
this.ux_cancel_button.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.ux_cancel_button.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
- this.ux_cancel_button.Location = new System.Drawing.Point(14, 311);
- this.ux_cancel_button.Margin = new System.Windows.Forms.Padding(4);
+ this.ux_cancel_button.Location = new System.Drawing.Point(10, 253);
this.ux_cancel_button.Name = "ux_cancel_button";
- this.ux_cancel_button.Size = new System.Drawing.Size(356, 78);
+ this.ux_cancel_button.Size = new System.Drawing.Size(267, 63);
this.ux_cancel_button.TabIndex = 11;
this.ux_cancel_button.Text = "Cancel";
this.ux_cancel_button.UseVisualStyleBackColor = true;
@@ -95,10 +90,9 @@ namespace MoMoney.Presentation.Winforms.Views
// ux_dont_update_button
//
this.ux_dont_update_button.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
- this.ux_dont_update_button.Location = new System.Drawing.Point(14, 226);
- this.ux_dont_update_button.Margin = new System.Windows.Forms.Padding(4);
+ this.ux_dont_update_button.Location = new System.Drawing.Point(10, 184);
this.ux_dont_update_button.Name = "ux_dont_update_button";
- this.ux_dont_update_button.Size = new System.Drawing.Size(356, 78);
+ this.ux_dont_update_button.Size = new System.Drawing.Size(267, 63);
this.ux_dont_update_button.TabIndex = 10;
this.ux_dont_update_button.Text = "Do&n\'t Update";
this.ux_dont_update_button.UseVisualStyleBackColor = true;
@@ -106,10 +100,9 @@ namespace MoMoney.Presentation.Winforms.Views
// ux_update_button
//
this.ux_update_button.Enabled = false;
- this.ux_update_button.Location = new System.Drawing.Point(13, 121);
- this.ux_update_button.Margin = new System.Windows.Forms.Padding(4);
+ this.ux_update_button.Location = new System.Drawing.Point(10, 98);
this.ux_update_button.Name = "ux_update_button";
- this.ux_update_button.Size = new System.Drawing.Size(356, 78);
+ this.ux_update_button.Size = new System.Drawing.Size(267, 63);
this.ux_update_button.TabIndex = 9;
this.ux_update_button.Text = "&Update";
this.ux_update_button.UseVisualStyleBackColor = true;
@@ -117,28 +110,27 @@ namespace MoMoney.Presentation.Winforms.Views
// ux_new_version
//
this.ux_new_version.AutoSize = true;
- this.ux_new_version.Location = new System.Drawing.Point(182, 49);
- this.ux_new_version.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.ux_new_version.Location = new System.Drawing.Point(136, 40);
this.ux_new_version.Name = "ux_new_version";
- this.ux_new_version.Size = new System.Drawing.Size(39, 17);
+ this.ux_new_version.Size = new System.Drawing.Size(32, 13);
this.ux_new_version.TabIndex = 16;
this.ux_new_version.Text = "New:";
//
// label5
//
this.label5.AutoSize = true;
- this.label5.Location = new System.Drawing.Point(253, 32);
- this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.label5.Location = new System.Drawing.Point(190, 26);
this.label5.Name = "label5";
- this.label5.Size = new System.Drawing.Size(20, 17);
+ this.label5.Size = new System.Drawing.Size(16, 13);
this.label5.TabIndex = 17;
this.label5.Text = "to";
//
// CheckForUpdatesView
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(388, 403);
+ this.CancelButton = this.ux_cancel_button;
+ this.ClientSize = new System.Drawing.Size(291, 327);
this.Controls.Add(this.label5);
this.Controls.Add(this.ux_new_version);
this.Controls.Add(this.label3);
@@ -148,7 +140,10 @@ namespace MoMoney.Presentation.Winforms.Views
this.Controls.Add(this.ux_cancel_button);
this.Controls.Add(this.ux_dont_update_button);
this.Controls.Add(this.ux_update_button);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
this.Name = "CheckForUpdatesView";
+ this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "MoMoney - Check For Updates";
((System.ComponentModel.ISupportInitialize)(this.ux_image)).EndInit();
product/Presentation/Winforms/Views/LogFileView.cs
@@ -1,4 +1,5 @@
๏ปฟusing MoMoney.Presentation.Views.Shell;
+using MoMoney.Presentation.Winforms.Resources;
namespace MoMoney.Presentation.Winforms.Views
{
@@ -11,7 +12,8 @@ namespace MoMoney.Presentation.Winforms.Views
public void display(string file_path)
{
- titled("Log File - {0}", file_path);
+ titled("Log File - {0}", file_path)
+ .icon(ApplicationIcons.ViewLog);
}
public void run(string file_contents)
product/Presentation/Winforms/Views/StatusBarView.cs
@@ -1,4 +1,5 @@
using System.Windows.Forms;
+using MoMoney.Presentation.Views;
using MoMoney.Presentation.Views.Shell;
using MoMoney.Presentation.Winforms.Resources;
@@ -21,5 +22,15 @@ namespace MoMoney.Presentation.Winforms.Views
x.Image = icon_to_display;
});
}
+
+ public void reset_progress_bar()
+ {
+ shell.region<ToolStripProgressBar>(x => { x.ProgressBar.Value = 0; });
+ }
+
+ public void notify()
+ {
+ shell.region<ToolStripProgressBar>(x => { x.Increment(10); });
+ }
}
}
\ No newline at end of file
product/Presentation/Winforms/Views/ViewAllBills.cs
@@ -3,6 +3,7 @@ using System.Linq;
using MoMoney.DTO;
using MoMoney.Presentation.Presenters.billing;
using MoMoney.Presentation.Views;
+using MoMoney.Presentation.Winforms.Resources;
namespace MoMoney.Presentation.Winforms.Views
{
@@ -11,7 +12,7 @@ namespace MoMoney.Presentation.Winforms.Views
public ViewAllBills()
{
InitializeComponent();
- titled("View Bills");
+ titled("View Bill Payments").icon(ApplicationIcons.ViewAllBillPayments);
}
public void attach_to(IViewAllBillsPresenter presenter)
product/Presentation/Winforms/Views/ViewAllIncome.cs
@@ -3,6 +3,7 @@ using Gorilla.Commons.Utility.Extensions;
using MoMoney.DTO;
using MoMoney.Presentation.Presenters.income;
using MoMoney.Presentation.Views.income;
+using MoMoney.Presentation.Winforms.Resources;
namespace MoMoney.Presentation.Winforms.Views
{
@@ -11,7 +12,7 @@ namespace MoMoney.Presentation.Winforms.Views
public ViewAllIncome()
{
InitializeComponent();
- titled("View All Income");
+ titled("View All Income").icon(ApplicationIcons.ViewAllIncome);
}
public void attach_to(IViewIncomeHistoryPresenter presenter)
product/Presentation/Winforms/Views/WelcomeScreen.cs
@@ -11,7 +11,7 @@ namespace MoMoney.Presentation.Winforms.Views
public WelcomeScreen()
{
InitializeComponent();
- titled("Getting Started");
+ titled("Getting Started").icon(ApplicationIcons.Home);
ux_open_existing_file_button.will_be_shown_as(ApplicationImages.OpenExistingFile)
.when_hovered_over_will_show(ApplicationImages.OpenExistingFileSelected)
product/Presentation/Presentation.csproj
@@ -103,6 +103,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Model\Messages\FinishedRunningCommand.cs" />
+ <Compile Include="Model\Messages\StartedRunningCommand.cs" />
<Compile Include="Model\Navigation\INavigationTreeVisitor.cs" />
<Compile Include="Model\Navigation\ITreeBranch.cs" />
<Compile Include="Model\Navigation\ITreeViewToRootNodeMapper.cs" />
@@ -536,6 +538,10 @@
<Project>{41D2B68B-031B-44FF-BAC5-7752D9E29F94}</Project>
<Name>Service.Contracts</Name>
</ProjectReference>
+ <ProjectReference Include="..\Service\Service.csproj">
+ <Project>{7EA4C557-6EF2-4B1F-85C8-5B3F51BAD8DB}</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.
product/Service/Infrastructure/Eventing/EventAggregator.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Threading;
+using Gorilla.Commons.Utility.Extensions;
+
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+ public class EventAggregator : IEventAggregator
+ {
+ readonly SynchronizationContext context;
+ readonly HashSet<object> subscribers;
+ readonly object mutex;
+
+ public EventAggregator(SynchronizationContext context)
+ {
+ subscribers = new HashSet<object>();
+ mutex = new object();
+ this.context = context;
+ }
+
+ public void subscribe_to<Event>(IEventSubscriber<Event> subscriber) where Event : IEvent
+ {
+ subscribe(subscriber);
+ }
+
+ public void subscribe<Listener>(Listener subscriber) where Listener : class
+ {
+ within_lock(() => subscribers.Add(subscriber));
+ }
+
+ public void publish<Event>(Event the_event_to_broadcast) where Event : IEvent
+ {
+ process(() => subscribers.call_on_each<IEventSubscriber<Event>>(x => x.notify(the_event_to_broadcast)));
+ }
+
+ public void publish<T>(Expression<Action<T>> call) where T : class
+ {
+ process(() => subscribers.each(x => x.call_on(call.Compile())));
+ }
+
+ public void publish<Event>() where Event : IEvent, new()
+ {
+ publish(new Event());
+ }
+
+ void within_lock(Action action)
+ {
+ lock (mutex) action();
+ }
+
+ void process(Action action)
+ {
+ context.Send(x => action(), new object());
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Eventing/EventAggregatorSpecs.cs
@@ -0,0 +1,79 @@
+using System.Data;
+using System.Threading;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using Rhino.Mocks;
+
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+ public abstract class behaves_like_event_aggregator : concerns_for<IEventAggregator, EventAggregator>
+ {
+ public override IEventAggregator create_sut()
+ {
+ return new EventAggregator(new SynchronizationContext());
+ }
+ }
+
+ [Concern(typeof(EventAggregator))]
+ public class when_a_event_is_raised_in_the_system : behaves_like_event_aggregator
+ {
+ it should_notify_all_subscribers_of_the_event = () =>
+ {
+ first_subscriber.was_told_to<IEventSubscriber<TestEvent>>(x => x.notify(message));
+ second_subscriber.was_told_to(x => x.notify(message));
+ };
+
+ it should_not_notify_any_subscribers_that_subscribed_to_a_different_event =
+ () => incorrect_subscriber.was_not_told_to(x => x.notify(Arg<AnotherEvent>.Is.Anything));
+
+ context c = () =>
+ {
+ message = new TestEvent();
+ first_subscriber = an<IEventSubscriber<TestEvent>>();
+ second_subscriber = an<IEventSubscriber<TestEvent>>();
+ incorrect_subscriber = an<IEventSubscriber<AnotherEvent>>();
+ };
+
+ because b = () =>
+ {
+ sut.subscribe_to(first_subscriber);
+ sut.subscribe(second_subscriber);
+ sut.publish(message);
+ };
+
+ static TestEvent message;
+ static IEventSubscriber<TestEvent> first_subscriber;
+ static IEventSubscriber<TestEvent> second_subscriber;
+ static IEventSubscriber<AnotherEvent> incorrect_subscriber;
+ }
+
+ [Concern(typeof(EventAggregator))]
+ public class when_publishing_a_call_to_all_subscribers : behaves_like_event_aggregator
+ {
+ it should_make_the_call_on_each_subscriber = () => connection.was_told_to(x => x.ChangeDatabase("localhost"));
+
+ context c = () =>
+ {
+ connection = an<IDbConnection>();
+ command = an<IDbCommand>();
+ };
+
+ because b = () =>
+ {
+ sut.subscribe(connection);
+ sut.subscribe(command);
+ sut.publish<IDbConnection>(x => x.ChangeDatabase("localhost"));
+ };
+
+ static IDbConnection connection;
+ static IDbCommand command;
+ }
+
+ public class TestEvent : IEvent
+ {
+ }
+
+ public class AnotherEvent : IEvent
+ {
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Eventing/IEvent.cs
@@ -0,0 +1,6 @@
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+ public interface IEvent
+ {
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Eventing/IEventAggregator.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Linq.Expressions;
+
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+ public interface IEventAggregator
+ {
+ void subscribe_to<Event>(IEventSubscriber<Event> subscriber) where Event : IEvent;
+ void subscribe<Listener>(Listener subscriber) where Listener : class;
+ void publish<Event>(Event the_event_to_broadcast) where Event : IEvent;
+ void publish<T>(Expression<Action<T>> call) where T : class;
+ void publish<Event>() where Event : IEvent, new();
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Eventing/IEventSubscriber.cs
@@ -0,0 +1,7 @@
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+ public interface IEventSubscriber<Event> where Event : IEvent
+ {
+ void notify(Event message);
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/AsynchronousCommandProcessor.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Threading;
+using Gorilla.Commons.Infrastructure.Threading;
+using Gorilla.Commons.Utility.Core;
+
+namespace MoMoney.Service.Infrastructure.Threading
+{
+ public class AsynchronousCommandProcessor : ICommandProcessor
+ {
+ readonly Queue<ICommand> queued_commands;
+ readonly EventWaitHandle manual_reset;
+ readonly IList<Thread> worker_threads;
+ bool keep_working;
+
+ public AsynchronousCommandProcessor()
+ {
+ queued_commands = new Queue<ICommand>();
+ worker_threads = new List<Thread>();
+ manual_reset = new ManualResetEvent(false);
+ }
+
+ public void add(Expression<Action> action_to_process)
+ {
+ add(new ActionCommand(action_to_process));
+ }
+
+ public void add(ICommand command_to_process)
+ {
+ lock (queued_commands)
+ {
+ if (queued_commands.Contains(command_to_process)) return;
+ queued_commands.Enqueue(command_to_process);
+ reset_thread();
+ }
+ }
+
+ public void run()
+ {
+ reset_thread();
+ keep_working = true;
+ var worker_thread = new Thread(run_commands);
+ worker_thread.SetApartmentState(ApartmentState.STA);
+ worker_threads.Add(worker_thread);
+ worker_thread.Start();
+ }
+
+ public void stop()
+ {
+ keep_working = false;
+ manual_reset.Set();
+ //manual_reset.Close();
+ }
+
+ [STAThread]
+ void run_commands()
+ {
+ while (keep_working)
+ {
+ manual_reset.WaitOne();
+ run_next_command();
+ }
+ }
+
+ void run_next_command()
+ {
+ ICommand command;
+ lock (queued_commands)
+ {
+ if (queued_commands.Count == 0)
+ {
+ manual_reset.Reset();
+ return;
+ }
+ command = queued_commands.Dequeue();
+ }
+ command.run();
+ reset_thread();
+ }
+
+ void reset_thread()
+ {
+ lock (queued_commands)
+ {
+ if (queued_commands.Count > 0) manual_reset.Set();
+ else manual_reset.Reset();
+ }
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/BackgroundThread.cs
@@ -0,0 +1,34 @@
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface IBackgroundThread : IDisposableCommand
+ {
+ }
+
+ public class BackgroundThread : IBackgroundThread
+ {
+ readonly IWorkerThread worker_thread;
+
+ public BackgroundThread(IDisposableCommand command_to_execute) : this(command_to_execute, new WorkerThread())
+ {
+ }
+
+ public BackgroundThread(IDisposableCommand command_to_execute, IWorkerThread worker_thread)
+ {
+ this.worker_thread = worker_thread;
+ worker_thread.DoWork += (sender, e) => command_to_execute.run();
+ worker_thread.Disposed += (sender, e) => command_to_execute.Dispose();
+ }
+
+ public void run()
+ {
+ worker_thread.begin();
+ }
+
+ public void Dispose()
+ {
+ worker_thread.Dispose();
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/BackgroundThreadFactory.cs
@@ -0,0 +1,33 @@
+using System;
+using Gorilla.Commons.Infrastructure.Container;
+using Gorilla.Commons.Utility.Core;
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface IBackgroundThreadFactory
+ {
+ IBackgroundThread create_for<CommandToExecute>() where CommandToExecute : IDisposableCommand;
+ IBackgroundThread create_for(Action action);
+ }
+
+ public class BackgroundThreadFactory : IBackgroundThreadFactory
+ {
+ private readonly IDependencyRegistry registry;
+
+ public BackgroundThreadFactory(IDependencyRegistry registry)
+ {
+ this.registry = registry;
+ }
+
+ public IBackgroundThread create_for<CommandToExecute>() where CommandToExecute : IDisposableCommand
+ {
+ return new BackgroundThread(registry.get_a<CommandToExecute>());
+ }
+
+ public IBackgroundThread create_for(Action action)
+ {
+ return new BackgroundThread(new DisposableCommand(action));
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/BackgroundThreadFactorySpecs.cs
@@ -0,0 +1,28 @@
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Infrastructure.Container;
+using Gorilla.Commons.Testing;
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ [Concern(typeof (BackgroundThreadFactory))]
+ public abstract class behaves_like_a_background_thread_factory : concerns_for<IBackgroundThreadFactory, BackgroundThreadFactory>
+ {
+ context c = () => { registry = the_dependency<IDependencyRegistry>(); };
+
+ protected static IDependencyRegistry registry;
+ }
+
+ [Concern(typeof (BackgroundThreadFactory))]
+ public class when_creating_a_background_thread : behaves_like_a_background_thread_factory
+ {
+ it should_return_an_instance_of_a_background_thread = () => result.should_not_be_null();
+
+ it should_lookup_an_instance_of_the_command_to_execute =
+ () => registry.was_told_to(r => r.get_a<IDisposableCommand>());
+
+ because b = () => { result = sut.create_for<IDisposableCommand>(); };
+
+ static IBackgroundThread result;
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/BackgroundThreadSpecs.cs
@@ -0,0 +1,42 @@
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using MoMoney.Utility.Core;
+using Rhino.Mocks;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ [Concern(typeof (BackgroundThread))]
+ public abstract class behaves_like_a_background_thread : concerns_for<IBackgroundThread, BackgroundThread>
+ {
+ context c = () =>
+ {
+ command_to_execute = the_dependency<IDisposableCommand>();
+ worker_thread = the_dependency<IWorkerThread>();
+ };
+
+ protected static IDisposableCommand command_to_execute;
+ protected static IWorkerThread worker_thread;
+ }
+
+ [Concern(typeof (BackgroundThread))]
+ public class when_executing_a_command_on_a_background_thread : behaves_like_a_background_thread
+ {
+ it should_execute_the_command_asynchronously = () => command_to_execute.was_told_to(c => c.run());
+
+ it should_start_the_worker_thread_asynchronously = () => worker_thread.was_told_to(t => t.begin());
+
+ because b = () =>
+ {
+ sut.run();
+ worker_thread.Raise(t => t.DoWork += null, null, null);
+ };
+ }
+
+ [Concern(typeof (BackgroundThread))]
+ public class when_disposing_a_background_thread : behaves_like_a_background_thread
+ {
+ it should_dispose_the_command_running_on_the_thread = () => worker_thread.was_told_to(w => w.Dispose());
+
+ because b = () => sut.Dispose();
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/CommandProcessor.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public class CommandProcessor : ICommandProcessor
+ {
+ readonly Queue<ICommand> queued_commands;
+
+ public CommandProcessor()
+ {
+ queued_commands = new Queue<ICommand>();
+ }
+
+ public void add(Expression<Action> action_to_process)
+ {
+ add(new ActionCommand(action_to_process));
+ }
+
+ public void add(ICommand command_to_process)
+ {
+ queued_commands.Enqueue(command_to_process);
+ }
+
+ public void run()
+ {
+ while (queued_commands.Count > 0) queued_commands.Dequeue().run();
+ }
+
+ public void stop()
+ {
+ queued_commands.Clear();
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/CommandProcessorSpecs.cs
@@ -0,0 +1,53 @@
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ [Concern(typeof (CommandProcessor))]
+ public abstract class behaves_like_a_command_processor : concerns_for<ICommandProcessor, CommandProcessor>
+ {
+ }
+
+ [Concern(typeof (CommandProcessor))]
+ public class when_running_all_the_queued_commands_waiting_for_execution : behaves_like_a_command_processor
+ {
+ it should_run_the_first_command_in_the_queue = () => first_command.was_told_to(f => f.run());
+
+ it should_run_the_second_command_in_the_queue = () => second_command.was_told_to(f => f.run());
+
+ context c = () =>
+ {
+ first_command = an<ICommand>();
+ second_command = an<ICommand>();
+ };
+
+ because b = () =>
+ {
+ sut.add(first_command);
+ sut.add(second_command);
+ sut.run();
+ };
+
+ static ICommand first_command;
+ static ICommand second_command;
+ }
+
+ [Concern(typeof (CommandProcessor))]
+ public class when_attempting_to_rerun_the_command_processor : behaves_like_a_command_processor
+ {
+ it should_not_re_run_the_commands_that_have_already_executed =
+ () => first_command.was_told_to(f => f.run()).only_once();
+
+ context c = () => { first_command = an<ICommand>(); };
+
+ because b = () =>
+ {
+ sut.add(first_command);
+ sut.run();
+ sut.run();
+ };
+
+ static ICommand first_command;
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/ICommandProcessor.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Linq.Expressions;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface ICommandProcessor : ICommand
+ {
+ void add(Expression<Action> action_to_process);
+ void add(ICommand command_to_process);
+ void stop();
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/IntervalTimer.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Timers;
+using Gorilla.Commons.Infrastructure.Threading;
+
+namespace MoMoney.Service.Infrastructure.Threading
+{
+ public interface ITimer
+ {
+ void start_notifying(ITimerClient client_to_be_notified, TimeSpan span);
+ void stop_notifying(ITimerClient client_to_stop_notifying);
+ }
+
+ public class IntervalTimer : ITimer
+ {
+ readonly ITimerFactory factory;
+ readonly IDictionary<ITimerClient, Timer> timers;
+
+ public IntervalTimer() : this(new TimerFactory())
+ {
+ }
+
+ public IntervalTimer(ITimerFactory factory)
+ {
+ this.factory = factory;
+ timers = new Dictionary<ITimerClient, Timer>();
+ }
+
+ public void start_notifying(ITimerClient client_to_be_notified, TimeSpan span)
+ {
+ stop_notifying(client_to_be_notified);
+
+ var timer = factory.create_for(span);
+ timer.Elapsed += (sender, args) => client_to_be_notified.notify();
+ timer.Start();
+ timers[client_to_be_notified] = timer;
+ }
+
+ public void stop_notifying(ITimerClient client_to_stop_notifying)
+ {
+ if (!timers.ContainsKey(client_to_stop_notifying)) return;
+ timers[client_to_stop_notifying].Stop();
+ timers[client_to_stop_notifying].Dispose();
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/IntervalTimerSpecs.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Timers;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using MoMoney.Service.Infrastructure.Threading;
+using Rhino.Mocks;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ [Concern(typeof (IntervalTimer))]
+ public abstract class behaves_like_an_interval_timer : concerns_for<ITimer, IntervalTimer>
+ {
+ context c = () => { factory = the_dependency<ITimerFactory>(); };
+
+ protected static ITimerFactory factory;
+ }
+
+ [Concern(typeof (IntervalTimer))]
+ public class when_starting_a_timer_for_a_new_client : behaves_like_an_interval_timer
+ {
+ static ITimerClient client;
+ static Timer timer;
+
+ it should_create_a_new_timer = () => factory.was_told_to(f => f.create_for(new TimeSpan(0, 10, 0)));
+
+ it should_start_the_timer = () => timer.was_told_to(t => t.Start());
+
+ context c = () =>
+ {
+ client = an<ITimerClient>();
+ timer = dependency<Timer>();
+
+ factory.is_told_to(f => f.create_for(new TimeSpan(0, 10, 0))).it_will_return(timer);
+ };
+
+ because b = () => sut.start_notifying(client, new TimeSpan(0, 10, 0));
+ }
+
+ [Concern(typeof (IntervalTimer))]
+ public class when_starting_a_timer_for_an_existing_client : behaves_like_an_interval_timer
+ {
+ it should_stop_the_previously_started_timer = () =>
+ {
+ first_timer.was_told_to(t => t.Stop());
+ first_timer.was_told_to(t => t.Dispose());
+ };
+
+ it should_start_a_new_timer = () => second_timer.was_told_to(t => t.Start());
+
+ context c = () =>
+ {
+ client = an<ITimerClient>();
+ first_timer = dependency<Timer>();
+ second_timer = dependency<Timer>();
+
+ factory.is_told_to(f => f.create_for(new TimeSpan(0, 1, 1))).it_will_return(first_timer);
+ factory.is_told_to(f => f.create_for(new TimeSpan(0, 2, 2))).it_will_return(second_timer);
+ };
+
+ because b = () =>
+ {
+ sut.start_notifying(client, new TimeSpan(0, 1, 1));
+ sut.start_notifying(client, new TimeSpan(0, 2, 2));
+ };
+
+ static ITimerClient client;
+ static Timer first_timer;
+ static Timer second_timer;
+ }
+
+ [Concern(typeof (IntervalTimer))]
+ public class when_a_timer_elapses : behaves_like_an_interval_timer
+ {
+ it should_notify_the_timer_client = () => client.was_told_to(c => c.notify());
+
+ static ITimerClient client;
+ static Timer timer;
+
+ context c = () =>
+ {
+ client = an<ITimerClient>();
+ timer = dependency<Timer>();
+ factory.is_told_to(f => f.create_for(Arg<TimeSpan>.Is.Anything)).it_will_return(timer);
+ };
+
+ because b = () =>
+ {
+ sut.start_notifying(client, new TimeSpan(0, 10, 0));
+ timer.Raise(t => t.Elapsed += null, timer, null);
+ };
+ }
+
+ [Concern(typeof (IntervalTimer))]
+ public class when_stopping_notifications_for_an_existing_timer_client : behaves_like_an_interval_timer
+ {
+ static ITimerClient client;
+ static Timer timer;
+
+ it should_stop_the_timer_that_was_started_for_the_client = () => timer.was_told_to(t => t.Stop());
+
+ it should_dispose_the_timer_that_was_started_for_the_client = () => timer.was_told_to(t => t.Dispose());
+
+ context c = () =>
+ {
+ client = an<ITimerClient>();
+ timer = dependency<Timer>();
+
+ when_the(factory).is_told_to(t => t.create_for(Arg<TimeSpan>.Is.Anything)).it_will_return(
+ timer);
+ };
+
+ because b = () =>
+ {
+ sut.start_notifying(client, new TimeSpan(0, 0, 1));
+ sut.stop_notifying(client);
+ };
+ }
+
+ [Concern(typeof (IntervalTimer))]
+ public class when_attempting_to_stop_notification_for_a_client_that_doesnt_have_a_timer_started_for_it :
+ behaves_like_an_interval_timer
+ {
+ it should_not_blow_up = () => { };
+
+ context c = () => { client = an<ITimerClient>(); };
+
+ because b = () => sut.stop_notifying(client);
+
+ static ITimerClient client;
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/ITimerClient.cs
@@ -0,0 +1,7 @@
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface ITimerClient
+ {
+ void notify();
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/IWorkerThread.cs
@@ -0,0 +1,12 @@
+using System;
+using System.ComponentModel;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface IWorkerThread : IDisposable
+ {
+ event DoWorkEventHandler DoWork;
+ event EventHandler Disposed;
+ void begin();
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/RaiseEventInterceptor.cs
@@ -0,0 +1,25 @@
+using Castle.Core.Interceptor;
+using MoMoney.Service.Infrastructure.Eventing;
+
+namespace Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors
+{
+ public interface IRaiseEventInterceptor<Event> : IInterceptor where Event : IEvent, new()
+ {
+ }
+
+ public class RaiseEventInterceptor<Event> : IRaiseEventInterceptor<Event> where Event : IEvent, new()
+ {
+ readonly IEventAggregator broker;
+
+ public RaiseEventInterceptor(IEventAggregator broker)
+ {
+ this.broker = broker;
+ }
+
+ public void Intercept(IInvocation invocation)
+ {
+ invocation.Proceed();
+ broker.publish(new Event());
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/RunOnBackgroundThreadInterceptor.cs
@@ -0,0 +1,25 @@
+using Castle.Core.Interceptor;
+using Gorilla.Commons.Infrastructure.Threading;
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors
+{
+ public class RunOnBackgroundThreadInterceptor<CommandToExecute> : IInterceptor
+ where CommandToExecute : IDisposableCommand
+ {
+ readonly IBackgroundThreadFactory thread_factory;
+
+ public RunOnBackgroundThreadInterceptor(IBackgroundThreadFactory thread_factory)
+ {
+ this.thread_factory = thread_factory;
+ }
+
+ public virtual void Intercept(IInvocation invocation)
+ {
+ using (thread_factory.create_for<CommandToExecute>())
+ {
+ invocation.Proceed();
+ }
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/RunOnBackgroundThreadInterceptorSpecs.cs
@@ -0,0 +1,45 @@
+using Castle.Core.Interceptor;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Infrastructure.Threading;
+using Gorilla.Commons.Testing;
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors
+{
+ [Concern(typeof (RunOnBackgroundThreadInterceptor<>))]
+ public abstract class behaves_like_background_thread_interceptor :
+ concerns_for<IInterceptor, RunOnBackgroundThreadInterceptor<IDisposableCommand>>
+ {
+ context c = () => { thread_factory = the_dependency<IBackgroundThreadFactory>(); };
+
+ static protected IBackgroundThreadFactory thread_factory;
+ }
+
+ [Concern(typeof (RunOnBackgroundThreadInterceptor<>))]
+ public class when_intercepting_a_call_to_a_method_that_takes_a_long_time_to_complete :
+ behaves_like_background_thread_interceptor
+ {
+ context c = () =>
+ {
+ invocation = an<IInvocation>();
+ background_thread = an<IBackgroundThread>();
+ thread_factory
+ .is_told_to(f => f.create_for<IDisposableCommand>())
+ .it_will_return(background_thread);
+ };
+
+ because b = () => sut.Intercept(invocation);
+
+ it should_display_a_progress_bar_on_a_background_thread =
+ () => thread_factory.was_told_to(f => f.create_for<IDisposableCommand>());
+
+ it should_proceed_with_the_orginal_invocation_on_the_actual_object =
+ () => invocation.was_told_to(i => i.Proceed());
+
+ it should_hide_the_progress_bar_when_the_invocation_is_completed =
+ () => background_thread.was_told_to(b => b.Dispose());
+
+ static IInvocation invocation;
+ static IBackgroundThread background_thread;
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/RunOnUIThread.cs
@@ -0,0 +1,25 @@
+using Castle.Core.Interceptor;
+using Gorilla.Commons.Infrastructure.Threading;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors
+{
+ public class RunOnUIThread : IInterceptor
+ {
+ readonly ISynchronizationContextFactory factory;
+
+ public RunOnUIThread() : this(Lazy.load<ISynchronizationContextFactory>())
+ {
+ }
+
+ public RunOnUIThread(ISynchronizationContextFactory factory)
+ {
+ this.factory = factory;
+ }
+
+ public void Intercept(IInvocation invocation)
+ {
+ factory.create().run(new ActionCommand(invocation.Proceed));
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/SynchronizationContextFactory.cs
@@ -0,0 +1,25 @@
+using System.Threading;
+using Gorilla.Commons.Infrastructure.Container;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface ISynchronizationContextFactory : IFactory<ISynchronizationContext>
+ {
+ }
+
+ public class SynchronizationContextFactory : ISynchronizationContextFactory
+ {
+ readonly IDependencyRegistry registry;
+
+ public SynchronizationContextFactory(IDependencyRegistry registry)
+ {
+ this.registry = registry;
+ }
+
+ public ISynchronizationContext create()
+ {
+ return new SynchronizedContext(registry.get_a<SynchronizationContext>());
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/SynchronizedCommand.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Threading;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface ISynchronizedCommand : IParameterizedCommand<Action>, IParameterizedCommand<ICommand>
+ {
+ }
+
+ public class SynchronizedCommand : ISynchronizedCommand
+ {
+ readonly SynchronizationContext context;
+
+ public SynchronizedCommand(SynchronizationContext context)
+ {
+ this.context = context;
+ }
+
+ public void run(Action item)
+ {
+ context.Post(x => item(), new object());
+ }
+
+ public void run(ICommand item)
+ {
+ run(item.run);
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/SynchronizedContext.cs
@@ -0,0 +1,25 @@
+using System.Threading;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface ISynchronizationContext : IParameterizedCommand<ICommand>
+ {
+ }
+
+ public class SynchronizedContext : ISynchronizationContext
+ {
+ readonly SynchronizationContext context;
+
+ public SynchronizedContext(SynchronizationContext context)
+ {
+ this.context = context;
+ }
+
+ public void run(ICommand item)
+ {
+ context.Post(x => item.run(), new object());
+ //context.Send(x => item.run(), new object());
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/Synchronizer.cs
@@ -0,0 +1,189 @@
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Security.Permissions;
+using System.Threading;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
+ public class Synchronizer : ISynchronizeInvoke, IDisposable
+ {
+ readonly WorkerThread worker_thread;
+
+ public Synchronizer()
+ {
+ worker_thread = new WorkerThread(this);
+ }
+
+ public bool InvokeRequired
+ {
+ get { return ReferenceEquals(Thread.CurrentThread, worker_thread); }
+ }
+
+ public IAsyncResult BeginInvoke(Delegate method, object[] args)
+ {
+ var result = new WorkItem(null, method, args);
+ worker_thread.queue_work_item(result);
+ return result;
+ }
+
+ public object EndInvoke(IAsyncResult result)
+ {
+ result.AsyncWaitHandle.WaitOne();
+ return ((WorkItem) result).MethodReturnedValue;
+ }
+
+ public object Invoke(Delegate method, object[] args)
+ {
+ return EndInvoke(BeginInvoke(method, args));
+ }
+
+ ~Synchronizer()
+ {
+ }
+
+ public void Dispose()
+ {
+ worker_thread.kill();
+ }
+
+ class WorkerThread
+ {
+ Thread thread;
+ bool end_loop;
+ readonly Mutex end_loop_mutex;
+ readonly AutoResetEvent item_added;
+ Synchronizer synchronizer;
+ readonly Queue work_item_queue;
+
+ internal WorkerThread(Synchronizer synchronizer)
+ {
+ this.synchronizer = synchronizer;
+ end_loop = false;
+ thread = null;
+ end_loop_mutex = new Mutex();
+ item_added = new AutoResetEvent(false);
+ work_item_queue = new Queue();
+ create_thread(true);
+ }
+
+ internal void queue_work_item(WorkItem work_item)
+ {
+ lock (work_item_queue.SyncRoot)
+ {
+ work_item_queue.Enqueue(work_item);
+ item_added.Set();
+ }
+ }
+
+ bool EndLoop
+ {
+ set
+ {
+ end_loop_mutex.WaitOne();
+ end_loop = value;
+ end_loop_mutex.ReleaseMutex();
+ }
+ get
+ {
+ var result = false;
+ end_loop_mutex.WaitOne();
+ result = end_loop;
+ end_loop_mutex.ReleaseMutex();
+ return result;
+ }
+ }
+
+ Thread create_thread(bool auto_start)
+ {
+ if (thread != null)
+ {
+ Debug.Assert(false);
+ return thread;
+ }
+ thread = new Thread(run) {Name = "Synchronizer Worker Thread"};
+ if (auto_start)
+ {
+ thread.Start();
+ }
+ return thread;
+ }
+
+ void start()
+ {
+ Debug.Assert(thread != null);
+ Debug.Assert(thread.IsAlive == false);
+ thread.Start();
+ }
+
+ bool queue_empty
+ {
+ get
+ {
+ lock (work_item_queue.SyncRoot)
+ {
+ if (work_item_queue.Count > 0)
+ {
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+
+ WorkItem GetNext()
+ {
+ if (queue_empty)
+ {
+ return null;
+ }
+ lock (work_item_queue.SyncRoot)
+ {
+ return (WorkItem) work_item_queue.Dequeue();
+ }
+ }
+
+ void run()
+ {
+ while (EndLoop == false)
+ {
+ while (queue_empty == false)
+ {
+ if (EndLoop)
+ {
+ return;
+ }
+ var workItem = GetNext();
+ workItem.CallBack();
+ }
+ item_added.WaitOne();
+ }
+ }
+
+ public void kill()
+ {
+ //Kill is called on client thread - must use cached thread object
+ Debug.Assert(thread != null);
+ if (thread.IsAlive == false)
+ {
+ return;
+ }
+ EndLoop = true;
+ item_added.Set();
+
+ //Wait for thread to die
+ thread.Join();
+ if (end_loop_mutex != null)
+ {
+ end_loop_mutex.Close();
+ }
+ if (item_added != null)
+ {
+ item_added.Close();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/ThreadingExtensions.cs
@@ -0,0 +1,12 @@
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public static class ThreadingExtensions
+ {
+ public static IBackgroundThread on_a_background_thread(this IDisposableCommand command)
+ {
+ return new BackgroundThread(command);
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/TimerFactory.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Timers;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public interface ITimerFactory
+ {
+ Timer create_for(TimeSpan span);
+ }
+
+ public class TimerFactory : ITimerFactory
+ {
+ public Timer create_for(TimeSpan span)
+ {
+ if (span.Seconds > 0) {
+ var milliseconds = span.Seconds*1000;
+ return new Timer(milliseconds);
+ }
+ return new Timer(span.Ticks);
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/TimerFactorySpecs.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Timers;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ [Concern(typeof (TimerFactory))]
+ public abstract class behaves_like_a_timer_factory : concerns_for<ITimerFactory, TimerFactory>
+ {
+ public override ITimerFactory create_sut()
+ {
+ return new TimerFactory();
+ }
+ }
+
+ [Concern(typeof (TimerFactory))]
+ public class when_creating_a_timer : behaves_like_a_timer_factory
+ {
+ it should_return_a_timer_with_the_correct_interval = () => result.Interval.should_be_equal_to(1000);
+
+ because b = () => { result = sut.create_for(new TimeSpan(0, 0, 1)); };
+
+ static Timer result;
+ }
+
+ [Concern(typeof (TimerFactory))]
+ public class when_creating_a_timer_with_an_interval_in_milliseconds : behaves_like_a_timer_factory
+ {
+ it should_return_a_timer_with_the_correct_polling_interval =
+ () => result.Interval.should_be_equal_to(milliseconds);
+
+ because b = () =>
+ {
+ var timer_interval = new TimeSpan(50);
+ milliseconds = 50;
+ result = sut.create_for(timer_interval);
+ };
+
+ static Timer result;
+ static double milliseconds;
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/WorkerThread.cs
@@ -0,0 +1,50 @@
+using System;
+using System.ComponentModel;
+using Gorilla.Commons.Infrastructure.Logging;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ public class WorkerThread : Component, IWorkerThread
+ {
+ static readonly object do_work_key = new object();
+ bool is_running;
+ readonly Action background_thread;
+
+ public WorkerThread()
+ {
+ background_thread = worker_thread_start;
+ }
+
+ public event DoWorkEventHandler DoWork
+ {
+ add { Events.AddHandler(do_work_key, value); }
+ remove { Events.RemoveHandler(do_work_key, value); }
+ }
+
+ public void begin()
+ {
+ if (is_running)
+ {
+ throw new InvalidOperationException("Worker Thread Is Already Running");
+ }
+ is_running = true;
+ background_thread.BeginInvoke(null, null);
+ }
+
+ void worker_thread_start()
+ {
+ try
+ {
+ var handler = (DoWorkEventHandler) Events[do_work_key];
+ if (handler != null)
+ {
+ handler(this, new DoWorkEventArgs(null));
+ }
+ }
+ catch (Exception e)
+ {
+ this.log().error(e);
+ }
+ }
+ }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/WorkItem.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Threading;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+ [Serializable]
+ internal class WorkItem : IAsyncResult
+ {
+ readonly object[] args;
+ readonly object async_state;
+ bool completed;
+ readonly Delegate method;
+ readonly ManualResetEvent reset_event;
+ object returned_value;
+
+ internal WorkItem(object async_state, Delegate method, object[] args)
+ {
+ this.async_state = async_state;
+ this.method = method;
+ this.args = args;
+ reset_event = new ManualResetEvent(false);
+ completed = false;
+ }
+
+ //IAsyncResult properties
+ object IAsyncResult.AsyncState
+ {
+ get { return async_state; }
+ }
+
+ WaitHandle IAsyncResult.AsyncWaitHandle
+ {
+ get { return reset_event; }
+ }
+
+ bool IAsyncResult.CompletedSynchronously
+ {
+ get { return false; }
+ }
+
+ bool IAsyncResult.IsCompleted
+ {
+ get { return Completed; }
+ }
+
+ bool Completed
+ {
+ get
+ {
+ lock (this)
+ {
+ return completed;
+ }
+ }
+ set
+ {
+ lock (this)
+ {
+ completed = value;
+ }
+ }
+ }
+
+ //This method is called on the worker thread to execute the method
+ internal void CallBack()
+ {
+ MethodReturnedValue = method.DynamicInvoke(args);
+ //Method is done. Signal the world
+ reset_event.Set();
+ Completed = true;
+ }
+
+ internal object MethodReturnedValue
+ {
+ get
+ {
+ object method_returned_value;
+ lock (this)
+ {
+ method_returned_value = returned_value;
+ }
+ return method_returned_value;
+ }
+ set
+ {
+ lock (this)
+ {
+ returned_value = value;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
product/Service/Service.csproj
@@ -35,6 +35,14 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\build\lib\test\bdd.doc\bdddoc.dll</HintPath>
</Reference>
+ <Reference Include="Castle.Core, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\build\lib\app\castle\Castle.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Castle.DynamicProxy2, Version=2.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\build\lib\app\castle\Castle.DynamicProxy2.dll</HintPath>
+ </Reference>
<Reference Include="developwithpassion.bdd, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\build\lib\test\developwithpassion\developwithpassion.bdd.dll</HintPath>
@@ -43,6 +51,10 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\build\lib\app\gorilla\gorilla.commons.infrastructure.dll</HintPath>
</Reference>
+ <Reference Include="gorilla.commons.infrastructure.thirdparty, Version=2009.9.5.2051, Culture=neutral, PublicKeyToken=687787ccb6c36c9f, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\build\lib\app\gorilla\gorilla.commons.infrastructure.thirdparty.dll</HintPath>
+ </Reference>
<Reference Include="gorilla.commons.utility, Version=2009.5.5.1633, Culture=neutral, PublicKeyToken=687787ccb6c36c9f, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\build\lib\app\gorilla\gorilla.commons.utility.dll</HintPath>
@@ -86,11 +98,43 @@
<Compile Include="Application\IEventLog.cs" />
<Compile Include="Application\RegisterNewCompanyCommand.cs" />
<Compile Include="Application\SaveNewBillCommand.cs" />
+ <Compile Include="Infrastructure\Eventing\EventAggregator.cs" />
+ <Compile Include="Infrastructure\Eventing\EventAggregatorSpecs.cs" />
+ <Compile Include="Infrastructure\Eventing\IEvent.cs" />
+ <Compile Include="Infrastructure\Eventing\IEventAggregator.cs" />
+ <Compile Include="Infrastructure\Eventing\IEventSubscriber.cs" />
<Compile Include="Infrastructure\Logging\LogFileTasks.cs" />
<Compile Include="Infrastructure\ProjectTasks.cs" />
<Compile Include="Infrastructure\Security\IsInRole.cs" />
<Compile Include="Infrastructure\Security\IsInRoleSpecs.cs" />
<Compile Include="Infrastructure\Security\Role.cs" />
+ <Compile Include="Infrastructure\Threading\AsynchronousCommandProcessor.cs" />
+ <Compile Include="Infrastructure\Threading\BackgroundThread.cs" />
+ <Compile Include="Infrastructure\Threading\BackgroundThreadFactory.cs" />
+ <Compile Include="Infrastructure\Threading\BackgroundThreadFactorySpecs.cs" />
+ <Compile Include="Infrastructure\Threading\BackgroundThreadSpecs.cs" />
+ <Compile Include="Infrastructure\Threading\CommandProcessor.cs" />
+ <Compile Include="Infrastructure\Threading\CommandProcessorSpecs.cs" />
+ <Compile Include="Infrastructure\Threading\ICommandProcessor.cs" />
+ <Compile Include="Infrastructure\Threading\IntervalTimer.cs" />
+ <Compile Include="Infrastructure\Threading\IntervalTimerSpecs.cs" />
+ <Compile Include="Infrastructure\Threading\ITimerClient.cs" />
+ <Compile Include="Infrastructure\Threading\IWorkerThread.cs" />
+ <Compile Include="Infrastructure\Threading\RaiseEventInterceptor.cs" />
+ <Compile Include="Infrastructure\Threading\RunOnBackgroundThreadInterceptor.cs" />
+ <Compile Include="Infrastructure\Threading\RunOnBackgroundThreadInterceptorSpecs.cs" />
+ <Compile Include="Infrastructure\Threading\RunOnUIThread.cs" />
+ <Compile Include="Infrastructure\Threading\SynchronizationContextFactory.cs" />
+ <Compile Include="Infrastructure\Threading\SynchronizedCommand.cs" />
+ <Compile Include="Infrastructure\Threading\SynchronizedContext.cs" />
+ <Compile Include="Infrastructure\Threading\Synchronizer.cs" />
+ <Compile Include="Infrastructure\Threading\ThreadingExtensions.cs" />
+ <Compile Include="Infrastructure\Threading\TimerFactory.cs" />
+ <Compile Include="Infrastructure\Threading\TimerFactorySpecs.cs" />
+ <Compile Include="Infrastructure\Threading\WorkerThread.cs">
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="Infrastructure\Threading\WorkItem.cs" />
<Compile Include="Infrastructure\Transactions\EmptyUnitOfWork.cs" />
<Compile Include="Infrastructure\Transactions\UnitOfWork.cs" />
<Compile Include="Infrastructure\Transactions\UnitOfWorkFactory.cs" />