Wrapping all view <-> presenter <-> manager related interactions into Mediator pattern

This commit is contained in:
Anton Kasyanov
2018-02-18 19:51:06 +02:00
parent b3a35cb344
commit 8110b5ce7e
21 changed files with 193 additions and 55 deletions

View File

@@ -113,10 +113,18 @@
<Compile Include="Configuration\IAppConfig.cs" /> <Compile Include="Configuration\IAppConfig.cs" />
<Compile Include="Configuration\IThumbnailConfiguration.cs" /> <Compile Include="Configuration\IThumbnailConfiguration.cs" />
<Compile Include="Configuration\ZoomAnchor.cs" /> <Compile Include="Configuration\ZoomAnchor.cs" />
<Compile Include="Mediatr\Handlers\Services\StartServicesHandler.cs" /> <Compile Include="Mediator\Handlers\Configuration\SaveConfigurationHandler.cs" />
<Compile Include="Mediatr\Handlers\Services\StopServicesHandler.cs" /> <Compile Include="Mediator\Handlers\Thumbnails\ThumbnailLocationUpdatedHandler.cs" />
<Compile Include="Mediatr\Messages\Services\StartServices.cs" /> <Compile Include="Mediator\Handlers\Thumbnails\ThumbnailSizeUpdatedHandler.cs" />
<Compile Include="Mediatr\Messages\Services\StopServices.cs" /> <Compile Include="Mediator\Handlers\Services\StartServiceHandler.cs" />
<Compile Include="Mediator\Handlers\Services\StopServiceHandler.cs" />
<Compile Include="Mediator\Messages\Base\NotificationBase.cs" />
<Compile Include="Mediator\Messages\Configuration\SaveConfiguration.cs" />
<Compile Include="Mediator\Messages\Services\StartService.cs" />
<Compile Include="Mediator\Messages\Services\StopService.cs" />
<Compile Include="Mediator\Messages\Thumbnails\ThumbnailLocationUpdated.cs" />
<Compile Include="Mediator\Messages\Thumbnails\ThumbnailSizeUpdated.cs" />
<Compile Include="Presenters\Interface\IMainFormPresenter.cs" />
<Compile Include="Services\Implementation\ProcessInfo.cs" /> <Compile Include="Services\Implementation\ProcessInfo.cs" />
<Compile Include="Services\Implementation\ProcessMonitor.cs" /> <Compile Include="Services\Implementation\ProcessMonitor.cs" />
<Compile Include="Services\Interface\IProcessInfo.cs" /> <Compile Include="Services\Interface\IProcessInfo.cs" />
@@ -134,14 +142,14 @@
<Compile Include="ApplicationBase\IPresenter.cs" /> <Compile Include="ApplicationBase\IPresenter.cs" />
<Compile Include="Services\Implementation\WindowManager.cs" /> <Compile Include="Services\Implementation\WindowManager.cs" />
<Compile Include="Services\Interop\User32NativeMethods.cs" /> <Compile Include="Services\Interop\User32NativeMethods.cs" />
<Compile Include="Presentation\MainPresenter.cs" /> <Compile Include="Presenters\Implementation\MainFormPresenter.cs" />
<Compile Include="Presentation\ViewCloseRequest.cs" /> <Compile Include="Presenters\ViewCloseRequest.cs" />
<Compile Include="Presentation\ViewZoomAnchorConverter.cs" /> <Compile Include="Presenters\ViewZoomAnchorConverter.cs" />
<Compile Include="UI\Interface\IThumbnailViewFactory.cs" /> <Compile Include="UI\Interface\IThumbnailViewFactory.cs" />
<Compile Include="Presentation\IThumbnailManager.cs" /> <Compile Include="Presenters\IThumbnailManager.cs" />
<Compile Include="UI\Implementation\ThumbnailDescriptionView.cs" /> <Compile Include="UI\Implementation\ThumbnailDescriptionView.cs" />
<Compile Include="UI\Factory\ThumbnailDescriptionViewFactory.cs" /> <Compile Include="UI\Factory\ThumbnailDescriptionViewFactory.cs" />
<Compile Include="UI\Interface\IMainView.cs" /> <Compile Include="UI\Interface\IMainFormView.cs" />
<Compile Include="ApplicationBase\IView.cs" /> <Compile Include="ApplicationBase\IView.cs" />
<Compile Include="UI\Interface\IThumbnailDescriptionView.cs" /> <Compile Include="UI\Interface\IThumbnailDescriptionView.cs" />
<Compile Include="UI\Interface\IThumbnailDescriptionViewFactory.cs" /> <Compile Include="UI\Interface\IThumbnailDescriptionViewFactory.cs" />
@@ -158,7 +166,7 @@
<Compile Include="Configuration\IConfigurationStorage.cs" /> <Compile Include="Configuration\IConfigurationStorage.cs" />
<Compile Include="UI\Interface\IThumbnailView.cs" /> <Compile Include="UI\Interface\IThumbnailView.cs" />
<Compile Include="UI\Factory\ThumbnailViewFactory.cs" /> <Compile Include="UI\Factory\ThumbnailViewFactory.cs" />
<Compile Include="Presentation\ThumbnailManager.cs" /> <Compile Include="Presenters\ThumbnailManager.cs" />
<Compile Include="UI\Implementation\ThumbnailOverlay.cs"> <Compile Include="UI\Implementation\ThumbnailOverlay.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>

View File

@@ -0,0 +1,25 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Configuration
{
sealed class SaveConfigurationHandler : IRequestHandler<SaveConfiguration>
{
private readonly IConfigurationStorage _storage;
public SaveConfigurationHandler(IConfigurationStorage storage)
{
this._storage = storage;
}
public Task Handle(SaveConfiguration message, CancellationToken cancellationToken)
{
this._storage.Save();
return Task.CompletedTask;
}
}
}

View File

@@ -4,18 +4,18 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.UI; using EveOPreview.UI;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers namespace EveOPreview.Mediator.Handlers.Services
{ {
sealed class StartServicesHandler : INotificationHandler<StartServices> sealed class StartServiceHandler : IRequestHandler<StartService>
{ {
private readonly IThumbnailManager _manager; private readonly IThumbnailManager _manager;
public StartServicesHandler(IThumbnailManager manager) public StartServiceHandler(IThumbnailManager manager)
{ {
this._manager = manager; this._manager = manager;
} }
public Task Handle(StartServices message, CancellationToken cancellationToken) public Task Handle(StartService message, CancellationToken cancellationToken)
{ {
this._manager.Activate(); this._manager.Activate();

View File

@@ -4,18 +4,18 @@ using EveOPreview.Mediator.Messages;
using EveOPreview.UI; using EveOPreview.UI;
using MediatR; using MediatR;
namespace EveOPreview.Mediator.Handlers namespace EveOPreview.Mediator.Handlers.Services
{ {
sealed class StopServicesHandler : INotificationHandler<StopServices> sealed class StopServiceHandler : IRequestHandler<StopService>
{ {
private readonly IThumbnailManager _manager; private readonly IThumbnailManager _manager;
public StopServicesHandler(IThumbnailManager manager) public StopServiceHandler(IThumbnailManager manager)
{ {
this._manager = manager; this._manager = manager;
} }
public Task Handle(StopServices message, CancellationToken cancellationToken) public Task Handle(StopService message, CancellationToken cancellationToken)
{ {
this._manager.Deactivate(); this._manager.Deactivate();

View File

@@ -0,0 +1,27 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails
{
sealed class ThumbnailLocationUpdatedHandler : INotificationHandler<ThumbnailLocationUpdated>
{
private readonly IMediator _mediator;
private readonly IThumbnailConfiguration _configuration;
public ThumbnailLocationUpdatedHandler(IMediator mediator, IThumbnailConfiguration configuration)
{
this._mediator = mediator;
this._configuration = configuration;
}
public Task Handle(ThumbnailLocationUpdated notification, CancellationToken cancellationToken)
{
this._configuration.SetThumbnailLocation(notification.ThumbnailName, notification.ActiveClientName, notification.Location);
return this._mediator.Send(new SaveConfiguration(), cancellationToken);
}
}
}

View File

@@ -0,0 +1,25 @@
using System.Threading;
using System.Threading.Tasks;
using EveOPreview.Mediator.Messages;
using EveOPreview.Presenters;
using MediatR;
namespace EveOPreview.Mediator.Handlers.Thumbnails
{
sealed class ThumbnailSizeUpdatedHandler : INotificationHandler<ThumbnailSizeUpdated>
{
private readonly IMainFormPresenter _presenter;
public ThumbnailSizeUpdatedHandler(MainFormPresenter presenter)
{
this._presenter = presenter;
}
public Task Handle(ThumbnailSizeUpdated notification, CancellationToken cancellationToken)
{
this._presenter.UpdateThumbnailSize(notification.Value);
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,14 @@
using MediatR;
namespace EveOPreview.Mediator.Messages
{
abstract class NotificationBase<TValue> : INotification
{
protected NotificationBase(TValue value)
{
this.Value = value;
}
public TValue Value { get; }
}
}

View File

@@ -2,7 +2,7 @@
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages
{ {
sealed class StopServices : INotification sealed class SaveConfiguration : IRequest
{ {
} }
} }

View File

@@ -2,7 +2,7 @@
namespace EveOPreview.Mediator.Messages namespace EveOPreview.Mediator.Messages
{ {
sealed class StartServices : INotification sealed class StartService : IRequest
{ {
} }
} }

View File

@@ -0,0 +1,8 @@
using MediatR;
namespace EveOPreview.Mediator.Messages
{
sealed class StopService : IRequest
{
}
}

View File

@@ -0,0 +1,21 @@
using System.Drawing;
using MediatR;
namespace EveOPreview.Mediator.Messages
{
sealed class ThumbnailLocationUpdated : INotification
{
public ThumbnailLocationUpdated(string thumbnailName, string activeClientName, Point location)
{
this.ThumbnailName = thumbnailName;
this.ActiveClientName = activeClientName;
this.Location = location;
}
public string ThumbnailName { get; }
public string ActiveClientName { get; }
public Point Location { get; }
}
}

View File

@@ -0,0 +1,12 @@
using System.Drawing;
namespace EveOPreview.Mediator.Messages
{
sealed class ThumbnailSizeUpdated : NotificationBase<Size>
{
public ThumbnailSizeUpdated(Size size)
: base(size)
{
}
}
}

View File

@@ -16,8 +16,5 @@ namespace EveOPreview.UI
Action<IList<IThumbnailView>> ThumbnailsAdded { get; set; } Action<IList<IThumbnailView>> ThumbnailsAdded { get; set; }
Action<IList<IThumbnailView>> ThumbnailsUpdated { get; set; } Action<IList<IThumbnailView>> ThumbnailsUpdated { get; set; }
Action<IList<IThumbnailView>> ThumbnailsRemoved { get; set; } Action<IList<IThumbnailView>> ThumbnailsRemoved { get; set; }
Action<String, String, Point> ThumbnailPositionChanged { get; set; }
Action<Size> ThumbnailSizeChanged { get; set; }
} }
} }

View File

@@ -4,11 +4,12 @@ using System.Diagnostics;
using System.Drawing; using System.Drawing;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages; using EveOPreview.Mediator.Messages;
using EveOPreview.UI;
using MediatR; using MediatR;
namespace EveOPreview.UI namespace EveOPreview.Presenters
{ {
public class MainPresenter : Presenter<IMainView> public class MainFormPresenter : Presenter<IMainFormView>, IMainFormPresenter
{ {
#region Private constants #region Private constants
private const string ForumUrl = @"https://meta.eveonline.com/t/4202"; private const string ForumUrl = @"https://meta.eveonline.com/t/4202";
@@ -25,7 +26,7 @@ namespace EveOPreview.UI
private bool _exitApplication; private bool _exitApplication;
#endregion #endregion
public MainPresenter(IApplicationController controller, IMainView view, IMediator mediator, IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage, public MainFormPresenter(IApplicationController controller, IMainFormView view, IMediator mediator, IThumbnailConfiguration configuration, IConfigurationStorage configurationStorage,
IThumbnailManager thumbnailManager, IThumbnailDescriptionViewFactory thumbnailDescriptionViewFactory) IThumbnailManager thumbnailManager, IThumbnailDescriptionViewFactory thumbnailDescriptionViewFactory)
: base(controller, view) : base(controller, view)
{ {
@@ -51,22 +52,19 @@ namespace EveOPreview.UI
this._thumbnailManager.ThumbnailsAdded = this.ThumbnailsAdded; this._thumbnailManager.ThumbnailsAdded = this.ThumbnailsAdded;
this._thumbnailManager.ThumbnailsUpdated = this.ThumbnailsUpdated; this._thumbnailManager.ThumbnailsUpdated = this.ThumbnailsUpdated;
this._thumbnailManager.ThumbnailsRemoved = this.ThumbnailsRemoved; this._thumbnailManager.ThumbnailsRemoved = this.ThumbnailsRemoved;
this._thumbnailManager.ThumbnailPositionChanged = this.ThumbnailPositionChanged;
this._thumbnailManager.ThumbnailSizeChanged = this.ThumbnailSizeChanged;
} }
private void Activate() private void Activate()
{ {
this.LoadApplicationSettings(); this.LoadApplicationSettings();
this.View.SetDocumentationUrl(MainPresenter.ForumUrl); this.View.SetDocumentationUrl(MainFormPresenter.ForumUrl);
this.View.SetVersionInfo(this.GetApplicationVersion()); this.View.SetVersionInfo(this.GetApplicationVersion());
if (this._configuration.MinimizeToTray) if (this._configuration.MinimizeToTray)
{ {
this.View.Minimize(); this.View.Minimize();
} }
this._mediator.Publish(new StartServices()); this._mediator.Send(new StartService());
} }
private void Minimize() private void Minimize()
@@ -83,7 +81,7 @@ namespace EveOPreview.UI
{ {
if (this._exitApplication || !this.View.MinimizeToTray) if (this._exitApplication || !this.View.MinimizeToTray)
{ {
this._mediator.Publish(new StopServices()).Wait(); this._mediator.Send(new StopService()).Wait();
this._thumbnailManager.Deactivate(); this._thumbnailManager.Deactivate();
this._configurationStorage.Save(); this._configurationStorage.Save();
@@ -215,17 +213,6 @@ namespace EveOPreview.UI
return thumbnailViews; return thumbnailViews;
} }
private void ThumbnailPositionChanged(String thumbnailName, String activeClientName, Point location)
{
this._configuration.SetThumbnailLocation(thumbnailName, activeClientName, location);
this._configurationStorage.Save();
}
private void ThumbnailSizeChanged(Size size)
{
this.View.ThumbnailSize = size;
}
private void UpdateThumbnailState(IntPtr thumbnailId) private void UpdateThumbnailState(IntPtr thumbnailId)
{ {
this._thumbnailManager.SetThumbnailState(thumbnailId, this._thumbnailDescriptionViews[thumbnailId].IsDisabled); this._thumbnailManager.SetThumbnailState(thumbnailId, this._thumbnailDescriptionViews[thumbnailId].IsDisabled);
@@ -233,7 +220,7 @@ namespace EveOPreview.UI
private void OpenDocumentationLink() private void OpenDocumentationLink()
{ {
ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainPresenter.ForumUrl).AbsoluteUri); ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.ForumUrl).AbsoluteUri);
Process.Start(processStartInfo); Process.Start(processStartInfo);
} }
@@ -248,5 +235,10 @@ namespace EveOPreview.UI
this._exitApplication = true; this._exitApplication = true;
this.View.Close(); this.View.Close();
} }
public void UpdateThumbnailSize(Size size)
{
this.View.ThumbnailSize = size;
}
} }
} }

View File

@@ -0,0 +1,9 @@
using System.Drawing;
namespace EveOPreview.Presenters
{
interface IMainFormPresenter
{
void UpdateThumbnailSize(Size size);
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Windows.Threading; using System.Windows.Threading;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using EveOPreview.Services; using EveOPreview.Services;
using MediatR; using MediatR;
@@ -18,6 +19,7 @@ namespace EveOPreview.UI
#endregion #endregion
#region Private fields #region Private fields
private readonly IMediator _mediator;
private readonly IProcessMonitor _processMonitor; private readonly IProcessMonitor _processMonitor;
private readonly IWindowManager _windowManager; private readonly IWindowManager _windowManager;
private readonly IThumbnailConfiguration _configuration; private readonly IThumbnailConfiguration _configuration;
@@ -34,6 +36,7 @@ namespace EveOPreview.UI
public ThumbnailManager(IMediator mediator, IThumbnailConfiguration configuration, IProcessMonitor processMonitor, IWindowManager windowManager, IThumbnailViewFactory factory) public ThumbnailManager(IMediator mediator, IThumbnailConfiguration configuration, IProcessMonitor processMonitor, IWindowManager windowManager, IThumbnailViewFactory factory)
{ {
this._mediator = mediator;
this._processMonitor = processMonitor; this._processMonitor = processMonitor;
this._windowManager = windowManager; this._windowManager = windowManager;
this._configuration = configuration; this._configuration = configuration;
@@ -59,10 +62,6 @@ namespace EveOPreview.UI
public Action<IList<IThumbnailView>> ThumbnailsRemoved { get; set; } public Action<IList<IThumbnailView>> ThumbnailsRemoved { get; set; }
public Action<String, String, Point> ThumbnailPositionChanged { get; set; }
public Action<Size> ThumbnailSizeChanged { get; set; }
public void Activate() public void Activate()
{ {
this._thumbnailUpdateTimer.Start(); this._thumbnailUpdateTimer.Start();
@@ -96,7 +95,7 @@ namespace EveOPreview.UI
entry.Value.Refresh(false); entry.Value.Refresh(false);
} }
this.ThumbnailSizeChanged?.Invoke(size); this._mediator.Publish(new ThumbnailSizeUpdated(size)); // This one runs asynchronously
this.EnableViewEvents(); this.EnableViewEvents();
} }
@@ -372,7 +371,7 @@ namespace EveOPreview.UI
view.Refresh(false); view.Refresh(false);
} }
private void ThumbnailViewMoved(IntPtr id) private async void ThumbnailViewMoved(IntPtr id)
{ {
if (this._ignoreViewEvents) if (this._ignoreViewEvents)
{ {
@@ -383,7 +382,7 @@ namespace EveOPreview.UI
if (this.IsManageableThumbnail(view)) if (this.IsManageableThumbnail(view))
{ {
this.ThumbnailPositionChanged?.Invoke(view.Title, this._activeClientTitle, view.ThumbnailLocation); await this._mediator.Publish(new ThumbnailLocationUpdated(view.Title, this._activeClientTitle, view.ThumbnailLocation));
} }
view.Refresh(false); view.Refresh(false);

View File

@@ -2,6 +2,7 @@ using System;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Presenters;
using EveOPreview.Services; using EveOPreview.Services;
using EveOPreview.UI; using EveOPreview.UI;
using MediatR; using MediatR;
@@ -34,7 +35,7 @@ namespace EveOPreview
IApplicationController controller = Program.InitializeApplicationController(); IApplicationController controller = Program.InitializeApplicationController();
Program.InitializeWinForms(); Program.InitializeWinForms();
controller.Run<MainPresenter>(); controller.Run<MainFormPresenter>();
} }
private static object GetInstanceToken() private static object GetInstanceToken()
@@ -97,7 +98,7 @@ namespace EveOPreview
IApplicationController controller = new ApplicationController(container); IApplicationController controller = new ApplicationController(container);
// UI classes // UI classes
controller.RegisterView<IMainView, MainForm>() controller.RegisterView<IMainFormView, MainForm>()
.RegisterView<IThumbnailView, ThumbnailView>() .RegisterView<IThumbnailView, ThumbnailView>()
.RegisterView<IThumbnailDescriptionView, ThumbnailDescriptionView>() .RegisterView<IThumbnailDescriptionView, ThumbnailDescriptionView>()
.RegisterInstance(new ApplicationContext()); .RegisterInstance(new ApplicationContext());

View File

@@ -5,7 +5,7 @@ using System.Windows.Forms;
namespace EveOPreview.UI namespace EveOPreview.UI
{ {
public partial class MainForm : Form, IMainView public partial class MainForm : Form, IMainFormView
{ {
#region Private fields #region Private fields
private readonly ApplicationContext _context; private readonly ApplicationContext _context;

View File

@@ -8,7 +8,7 @@ namespace EveOPreview.UI
/// Main view interface /// Main view interface
/// Presenter uses it to access GUI properties /// Presenter uses it to access GUI properties
/// </summary> /// </summary>
public interface IMainView : IView public interface IMainFormView : IView
{ {
bool MinimizeToTray { get; set; } bool MinimizeToTray { get; set; }