Skip to content

Instantly share code, notes, and snippets.

@MarkNijhof
Created August 1, 2010 22:52
Show Gist options
  • Save MarkNijhof/503862 to your computer and use it in GitHub Desktop.
Save MarkNijhof/503862 to your computer and use it in GitHub Desktop.
namespace Fohjin.DDD.BankApplication.Views
{
public partial class ClientSearchForm : Form, IClientSearchFormView
{
public ClientSearchForm()
{
InitializeComponent();
RegisterClientEvents();
}
public event EventAction OnCreateNewClient;
public event EventAction OnOpenSelectedClient;
private void RegisterClientEvents()
{
addANewClientToolStripMenuItem.Click += (s, e) => OnCreateNewClient();
_clients.Click += (s, e) => OnOpenSelectedClient();
}
public IEnumerable<ClientReport> Clients
{
get { return (IEnumerable<ClientReport>)_clients.DataSource; }
set { _clients.DataSource = value; }
}
public ClientReport GetSelectedClient()
{
return (ClientReport)_clients.SelectedItem;
}
}
}
namespace Fohjin.DDD.BankApplication.Views
{
public interface IClientSearchFormView : IView
{
IEnumerable<ClientReport> Clients { get; set; }
ClientReport GetSelectedClient();
event EventAction OnCreateNewClient;
event EventAction OnOpenSelectedClient;
}
}
namespace Fohjin.DDD.BankApplication.Presenters
{
public class ClientSearchFormPresenter : Presenter<IClientSearchFormView>, IClientSearchFormPresenter
{
private readonly IClientSearchFormView _clientSearchFormView;
public ClientSearchFormPresenter(IClientSearchFormView clientSearchFormView) : base(clientSearchFormView)
{
_clientSearchFormView = clientSearchFormView;
}
public void CreateNewClient()
{
// Do something
}
public void OpenSelectedClient()
{
// Do something
}
public void Display()
{
LoadData();
try
{
_clientSearchFormView.ShowDialog();
}
finally
{
_clientSearchFormView.Dispose();
}
}
private void LoadData()
{
// Do something
}
}
}
namespace Fohjin.DDD.BankApplication
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ApplicationBootStrapper.BootStrap();
var clientSearchFormPresenter = ObjectFactory.GetInstance<IClientSearchFormPresenter>();
Application.EnableVisualStyles();
clientSearchFormPresenter.Display();
}
}
}
namespace Fohjin.DDD.BankApplication.Presenters
{
public abstract class Presenter<TView> where TView : class, IView
{
protected Presenter(TView view)
{
HookUpViewEvents(view);
}
private void HookUpViewEvents(TView view)
{
var viewDefinedEvents = GetViewDefinedEvents();
var viewEvents = GetViewEvents(view, viewDefinedEvents);
var presenterEventHandlers = GetPresenterEventHandlers(viewDefinedEvents, this);
foreach (var viewDefinedEvent in viewDefinedEvents)
{
var eventInfo = viewEvents[viewDefinedEvent];
var methodInfo = GetTheEventHandler(viewDefinedEvent, presenterEventHandlers, eventInfo);
WireUpTheEventAndEventHandler(view, eventInfo, methodInfo);
}
}
private MethodInfo GetTheEventHandler(string viewDefinedEvent, IDictionary<string, MethodInfo> presenterEventHandlers, EventInfo eventInfo)
{
var substring = viewDefinedEvent.Substring(2);
if (!presenterEventHandlers.ContainsKey(substring))
throw new Exception(string.Format("\n\nThere is no event handler for event '{0}' on presenter '{1}' expected '{2}'\n\n", eventInfo.Name, GetType().FullName, substring));
return presenterEventHandlers[substring];
}
private void WireUpTheEventAndEventHandler(TView view, EventInfo eventInfo, MethodInfo methodInfo)
{
var newDelegate = Delegate.CreateDelegate(typeof(EventAction), this, methodInfo);
eventInfo.AddEventHandler(view, newDelegate);
}
private static IDictionary<string, MethodInfo> GetPresenterEventHandlers<TPresenter>(ICollection<string> actionProperties, TPresenter presenter)
{
return presenter
.GetType()
.GetMethods(BindingFlags.Instance | BindingFlags.Public)
.Where(x => Contains(actionProperties, x))
.ToList()
.Select(x => new KeyValuePair<string, MethodInfo>(x.Name, x))
.ToDictionary(x => x.Key, x => x.Value);
}
private static List<string> GetViewDefinedEvents()
{
return typeof(TView).GetEvents().Select(x => x.Name).ToList();
}
private static IDictionary<string, EventInfo> GetViewEvents(TView view, ICollection<string> actionProperties)
{
return view
.GetType()
.GetEvents()
.Where(x => Contains(actionProperties, x))
.ToList()
.Select(x => new KeyValuePair<string, EventInfo>(x.Name, x))
.ToDictionary(x => x.Key, x => x.Value);
}
private static bool Contains(ICollection<string> actionProperties, EventInfo x)
{
return actionProperties.Contains(x.Name);
}
private static bool Contains(ICollection<string> actionProperties, MethodInfo x)
{
return actionProperties.Contains(string.Format("On{0}", x.Name));
}
}
}
namespace Test.Fohjin.DDD.Scenarios.Opening_the_bank_application
{
public class When_in_the_GUI_openeing_the_bank_application : PresenterTestFixture<ClientSearchFormPresenter>
{
private List<ClientReport> _clientReports;
protected override void SetupDependencies()
{
_clientReports = new List<ClientReport> { new ClientReport(Guid.NewGuid(), "Client Name") };
OnDependency<IReportingRepository>()
.Setup(x => x.GetByExample<ClientReport>(null))
.Returns(_clientReports);
}
protected override void When()
{
Presenter.Display();
}
[Then]
public void Then_show_dialog_will_be_called_on_the_view()
{
On<IClientSearchFormView>().VerifyThat.Method(x => x.ShowDialog()).WasCalled();
}
[Then]
public void Then_client_report_data_from_the_reporting_repository_is_being_loaded_into_the_view()
{
On<IClientSearchFormView>().VerifyThat.ValueIsSetFor(x => x.Clients = _clientReports);
}
}
}
namespace Test.Fohjin.DDD.Scenarios.Adding_a_new_client
{
public class When_in_the_GUI_adding_a_new_client : PresenterTestFixture<ClientSearchFormPresenter>
{
protected override void When()
{
On<IClientSearchFormView>().FireEvent(x => x.OnCreateNewClient += delegate { });
}
[Then]
public void Then_client_report_data_from_the_reporting_repository_is_being_loaded_into_the_view()
{
On<IClientDetailsPresenter>().VerifyThat.Method(x => x.SetClient(null)).WasCalled();
}
[Then]
public void Then_display_will_be_called_on_the_view()
{
On<IClientDetailsPresenter>().VerifyThat.Method(x => x.Display()).WasCalled();
}
}
}
namespace Test.Fohjin.DDD.Scenarios.Displaying_client_details
{
public class When_in_the_GUI_opening_an_existing_client : PresenterTestFixture<ClientSearchFormPresenter>
{
private ClientReport _clientReport;
protected override void SetupDependencies()
{
OnDependency<IPopupPresenter>()
.Setup(x => x.CatchPossibleException(It.IsAny<Action>()))
.Callback<Action>(x => x());
_clientReport = new ClientReport(Guid.NewGuid(), "Client Name");
OnDependency<IClientSearchFormView>()
.Setup(x => x.GetSelectedClient())
.Returns(_clientReport);
}
protected override void When()
{
On<IClientSearchFormView>().FireEvent(x => x.OnOpenSelectedClient += delegate { });
}
[Then]
public void Then_get_selected_client_will_be_called_on_the_view()
{
On<IClientSearchFormView>().VerifyThat.Method(x => x.GetSelectedClient()).WasCalled();
}
[Then]
public void Then_client_report_data_from_the_reporting_repository_is_being_loaded_into_the_view()
{
On<IClientDetailsPresenter>().VerifyThat.Method(x => x.SetClient(_clientReport)).WasCalled();
}
[Then]
public void Then_display_will_be_called_on_the_view()
{
On<IClientDetailsPresenter>().VerifyThat.Method(x => x.Display()).WasCalled();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment