wip
This commit is contained in:
@@ -24,7 +24,7 @@ public sealed class NavigateAction :
|
|||||||
{
|
{
|
||||||
if (frameworkElement.DataContext is IObservableViewModel observableViewModel)
|
if (frameworkElement.DataContext is IObservableViewModel observableViewModel)
|
||||||
{
|
{
|
||||||
observableViewModel.Mediator.PublishAsync(new Navigate(Path))
|
observableViewModel.Publisher.PublishAsync(new Navigate(Path))
|
||||||
.GetAwaiter().GetResult();
|
.GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ using Microsoft.UI.Xaml.Markup;
|
|||||||
|
|
||||||
namespace Hyperbar.UI.Windows;
|
namespace Hyperbar.UI.Windows;
|
||||||
|
|
||||||
|
public class ViewModelBinder
|
||||||
|
{
|
||||||
|
public void Bind(object viewModel,
|
||||||
|
FrameworkElement view)
|
||||||
|
{
|
||||||
|
view.DataContext ??= viewModel;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public class ViewModelTemplate(IViewModelTemplateDescriptorProvider descriptors) :
|
public class ViewModelTemplate(IViewModelTemplateDescriptorProvider descriptors) :
|
||||||
DataTemplateSelector,
|
DataTemplateSelector,
|
||||||
IViewModelTemplate
|
IViewModelTemplate
|
||||||
@@ -19,7 +28,7 @@ public class ViewModelTemplate(IViewModelTemplateDescriptorProvider descriptors)
|
|||||||
DependencyObject container) =>
|
DependencyObject container) =>
|
||||||
SelectTemplateCore(item);
|
SelectTemplateCore(item);
|
||||||
|
|
||||||
private DataTemplate CreateDataTemplate(IViewModelTemplateDescriptor descriptor)
|
private static DataTemplate CreateDataTemplate(IViewModelTemplateDescriptor descriptor)
|
||||||
{
|
{
|
||||||
string xamlString = @$"
|
string xamlString = @$"
|
||||||
<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
|
<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
using Hyperbar.Interop.Windows;
|
using Hyperbar.Interop.Windows;
|
||||||
using Microsoft.UI.Windowing;
|
using Microsoft.UI.Windowing;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
|
||||||
using Windows.Graphics;
|
using Windows.Graphics;
|
||||||
using WinRT.Interop;
|
using WinRT.Interop;
|
||||||
|
|
||||||
namespace Hyperbar.UI.Windows;
|
namespace Hyperbar.UI.Windows;
|
||||||
|
|
||||||
public class NavigationItemTemplateSelector :
|
|
||||||
DataTemplateSelector
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
public static class WindowExtensions
|
public static class WindowExtensions
|
||||||
{
|
{
|
||||||
public static WindowMessageListener CreateMessageListener(this Window window) =>
|
public static WindowMessageListener CreateMessageListener(this Window window) =>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class WindowHandler :
|
|||||||
public Task Handle(Navigate<Window> args,
|
public Task Handle(Navigate<Window> args,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (args.Template is Window window)
|
if (args.View is Window window)
|
||||||
{
|
{
|
||||||
if (window.Content is FrameworkElement content)
|
if (window.Content is FrameworkElement content)
|
||||||
{
|
{
|
||||||
@@ -33,8 +33,8 @@ public class WindowHandler :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ViewModelBinder.Bind(args.ViewModel, content);
|
||||||
window.Closed += HandleClosed;
|
window.Closed += HandleClosed;
|
||||||
content.DataContext = args.Content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.Activate();
|
window.Activate();
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ namespace Hyperbar.Widget.MediaController.Windows;
|
|||||||
|
|
||||||
public partial class MediaButtonViewModel<TMediaButton>(IServiceProvider serviceProvider,
|
public partial class MediaButtonViewModel<TMediaButton>(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IRelayCommand invokeCommand) :
|
IRelayCommand invokeCommand) :
|
||||||
WidgetComponentViewModel(serviceProvider, serviceFactory, mediator, disposer),
|
WidgetComponentViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer),
|
||||||
INotificationHandler<Changed<MediaButton<TMediaButton>>>,
|
INotificationHandler<Changed<MediaButton<TMediaButton>>>,
|
||||||
IMediaButtonViewModel
|
IMediaButtonViewModel
|
||||||
{
|
{
|
||||||
@@ -29,5 +30,5 @@ public partial class MediaButtonViewModel<TMediaButton>(IServiceProvider service
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override async Task InitializeAsync() =>
|
public override async Task InitializeAsync() =>
|
||||||
await Mediator.PublishAsync<Request<TMediaButton>>();
|
await Publisher.PublishAsync<Request<TMediaButton>>();
|
||||||
}
|
}
|
||||||
@@ -14,23 +14,24 @@ public class MediaController :
|
|||||||
IDisposable
|
IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDisposer disposer;
|
private readonly IDisposer disposer;
|
||||||
private readonly IMediator mediator;
|
private readonly IPublisher publisher;
|
||||||
private readonly GlobalSystemMediaTransportControlsSession session;
|
private readonly GlobalSystemMediaTransportControlsSession session;
|
||||||
|
|
||||||
private bool isNextEnabled;
|
private bool isNextEnabled;
|
||||||
private bool isPreviousEnabled;
|
private bool isPreviousEnabled;
|
||||||
private GlobalSystemMediaTransportControlsSessionPlaybackStatus playbackStatus;
|
private GlobalSystemMediaTransportControlsSessionPlaybackStatus playbackStatus;
|
||||||
|
|
||||||
public MediaController(IMediator mediator,
|
public MediaController(IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
GlobalSystemMediaTransportControlsSession session)
|
GlobalSystemMediaTransportControlsSession session)
|
||||||
{
|
{
|
||||||
this.mediator = mediator;
|
this.publisher = publisher;
|
||||||
this.disposer = disposer;
|
this.disposer = disposer;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
|
||||||
disposer.Add(this);
|
disposer.Add(this);
|
||||||
mediator.Subscribe(this);
|
subscriber.Add(this);
|
||||||
|
|
||||||
session.MediaPropertiesChanged += OnMediaPropertiesChanged;
|
session.MediaPropertiesChanged += OnMediaPropertiesChanged;
|
||||||
session.PlaybackInfoChanged += OnPlaybackInfoChanged;
|
session.PlaybackInfoChanged += OnPlaybackInfoChanged;
|
||||||
@@ -117,7 +118,7 @@ public class MediaController :
|
|||||||
buffer = memoryStream.ToArray();
|
buffer = memoryStream.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
await mediator.PublishAsync(new Changed<MediaInformation>(new MediaInformation(mediaProperties.Title,
|
await publisher.PublishAsync(new Changed<MediaInformation>(new MediaInformation(mediaProperties.Title,
|
||||||
mediaProperties.Artist, buffer)));
|
mediaProperties.Artist, buffer)));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@@ -133,7 +134,7 @@ public class MediaController :
|
|||||||
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo =
|
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo =
|
||||||
session.GetPlaybackInfo();
|
session.GetPlaybackInfo();
|
||||||
|
|
||||||
await mediator.PublishAsync(new Changed<MediaButton<MediaPlayPauseButton>>(new
|
await publisher.PublishAsync(new Changed<MediaButton<MediaPlayPauseButton>>(new
|
||||||
MediaButton<MediaPlayPauseButton>(playbackInfo.PlaybackStatus is
|
MediaButton<MediaPlayPauseButton>(playbackInfo.PlaybackStatus is
|
||||||
GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing ?
|
GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing ?
|
||||||
new MediaButtonPlaying() :
|
new MediaButtonPlaying() :
|
||||||
@@ -142,7 +143,7 @@ public class MediaController :
|
|||||||
bool isPreviousEnabled = playbackInfo.Controls.IsPreviousEnabled;
|
bool isPreviousEnabled = playbackInfo.Controls.IsPreviousEnabled;
|
||||||
if (this.isPreviousEnabled != isPreviousEnabled)
|
if (this.isPreviousEnabled != isPreviousEnabled)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Changed<MediaButton<MediaPreviousButton>>(new
|
await publisher.PublishAsync(new Changed<MediaButton<MediaPreviousButton>>(new
|
||||||
MediaButton<MediaPreviousButton>(isPreviousEnabled ? new MediaButtonEnabled() :
|
MediaButton<MediaPreviousButton>(isPreviousEnabled ? new MediaButtonEnabled() :
|
||||||
new MediaButtonDisabled())));
|
new MediaButtonDisabled())));
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ public class MediaController :
|
|||||||
bool isNextEnabled = playbackInfo.Controls.IsNextEnabled;
|
bool isNextEnabled = playbackInfo.Controls.IsNextEnabled;
|
||||||
if (this.isNextEnabled != isNextEnabled)
|
if (this.isNextEnabled != isNextEnabled)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Changed<MediaButton<MediaNextButton>>(new
|
await publisher.PublishAsync(new Changed<MediaButton<MediaNextButton>>(new
|
||||||
MediaButton<MediaNextButton>(isNextEnabled ? new MediaButtonEnabled() :
|
MediaButton<MediaNextButton>(isNextEnabled ? new MediaButtonEnabled() :
|
||||||
new MediaButtonDisabled())));
|
new MediaButtonDisabled())));
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Hyperbar.Widget.MediaController.Windows;
|
namespace Hyperbar.Widget.MediaController.Windows;
|
||||||
|
|
||||||
public class MediaControllerHandler(IMediator mediator,
|
public class MediaControllerHandler(IPublisher publisher,
|
||||||
IServiceScopeProvider<MediaController> scopeProvider,
|
IServiceScopeProvider<MediaController> scopeProvider,
|
||||||
ICache<MediaController, MediaControllerViewModel> cache) :
|
ICache<MediaController, MediaControllerViewModel> cache) :
|
||||||
INotificationHandler<Create<MediaController>>,
|
INotificationHandler<Create<MediaController>>,
|
||||||
@@ -18,7 +18,7 @@ public class MediaControllerHandler(IMediator mediator,
|
|||||||
factory.Create(mediaController) is MediaControllerViewModel viewModel)
|
factory.Create(mediaController) is MediaControllerViewModel viewModel)
|
||||||
{
|
{
|
||||||
cache.Add(mediaController, viewModel);
|
cache.Add(mediaController, viewModel);
|
||||||
await mediator.PublishAsync(new Create<MediaControllerViewModel>(viewModel), cancellationToken);
|
await publisher.PublishAsync(new Create<MediaControllerViewModel>(viewModel), cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ public class MediaControllerHandler(IMediator mediator,
|
|||||||
cache.TryGetValue(mediaController, out MediaControllerViewModel? viewModel) &&
|
cache.TryGetValue(mediaController, out MediaControllerViewModel? viewModel) &&
|
||||||
viewModel is not null)
|
viewModel is not null)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Remove<MediaControllerViewModel>(viewModel), cancellationToken);
|
await publisher.PublishAsync(new Remove<MediaControllerViewModel>(viewModel), cancellationToken);
|
||||||
cache.Remove(mediaController);
|
cache.Remove(mediaController);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using Windows.Media.Control;
|
|||||||
|
|
||||||
namespace Hyperbar.Widget.MediaController.Windows;
|
namespace Hyperbar.Widget.MediaController.Windows;
|
||||||
|
|
||||||
public class MediaControllerService(IMediator mediator,
|
public class MediaControllerService(IPublisher publisher,
|
||||||
IFactory<GlobalSystemMediaTransportControlsSession, MediaController> factory) :
|
IFactory<GlobalSystemMediaTransportControlsSession, MediaController> factory) :
|
||||||
IHostedService
|
IHostedService
|
||||||
{
|
{
|
||||||
@@ -34,7 +34,7 @@ public class MediaControllerService(IMediator mediator,
|
|||||||
{
|
{
|
||||||
if (factory.Create(session) is MediaController mediaController)
|
if (factory.Create(session) is MediaController mediaController)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Create<MediaController>(mediaController));
|
await publisher.PublishAsync(new Create<MediaController>(mediaController));
|
||||||
cache.Add(new KeyValuePair<GlobalSystemMediaTransportControlsSession, MediaController>(session,
|
cache.Add(new KeyValuePair<GlobalSystemMediaTransportControlsSession, MediaController>(session,
|
||||||
mediaController));
|
mediaController));
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ public class MediaControllerService(IMediator mediator,
|
|||||||
{
|
{
|
||||||
if (!sessions.Any(x => x.SourceAppUserModelId == session.Key.SourceAppUserModelId))
|
if (!sessions.Any(x => x.SourceAppUserModelId == session.Key.SourceAppUserModelId))
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Remove<MediaController>(session.Value));
|
await publisher.PublishAsync(new Remove<MediaController>(session.Value));
|
||||||
cache.Remove(session);
|
cache.Remove(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,21 +10,22 @@ public class MediaControllerViewModel :
|
|||||||
public MediaControllerViewModel(IViewModelTemplate template,
|
public MediaControllerViewModel(IViewModelTemplate template,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IDisposer disposer) : base(serviceProvider, serviceFactory, mediator, disposer)
|
ISubscriber subscriber,
|
||||||
|
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
Template = template;
|
Template = template;
|
||||||
|
|
||||||
Add<MediaInformationViewModel>();
|
Add<MediaInformationViewModel>();
|
||||||
|
|
||||||
Add<MediaButtonViewModel<MediaPreviousButton>>(new RelayCommand(async () =>
|
Add<MediaButtonViewModel<MediaPreviousButton>>(new RelayCommand(async () =>
|
||||||
await mediator.PublishAsync<Request<MediaPrevious>>()));
|
await publisher.PublishAsync<Request<MediaPrevious>>()));
|
||||||
|
|
||||||
Add<MediaButtonViewModel<MediaPlayPauseButton>>(new RelayCommand(async () =>
|
Add<MediaButtonViewModel<MediaPlayPauseButton>>(new RelayCommand(async () =>
|
||||||
await mediator.PublishAsync<Request<MediaPlayPause>>()));
|
await publisher.PublishAsync<Request<MediaPlayPause>>()));
|
||||||
|
|
||||||
Add<MediaButtonViewModel<MediaNextButton>>(new RelayCommand(async () =>
|
Add<MediaButtonViewModel<MediaNextButton>>(new RelayCommand(async () =>
|
||||||
await mediator.PublishAsync<Request<MediaNext>>()));
|
await publisher.PublishAsync<Request<MediaNext>>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewModelTemplate Template { get; }
|
public IViewModelTemplate Template { get; }
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ namespace Hyperbar.Widget.MediaController.Windows;
|
|||||||
public class MediaControllerWidgetViewModel(IViewModelTemplate template,
|
public class MediaControllerWidgetViewModel(IViewModelTemplate template,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IEnumerable<MediaControllerViewModel> items) :
|
IEnumerable<MediaControllerViewModel> items) :
|
||||||
ObservableCollectionViewModel<MediaControllerViewModel>(serviceProvider, serviceFactory, mediator, disposer, items),
|
ObservableCollectionViewModel<MediaControllerViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer, items),
|
||||||
IWidgetViewModel
|
IWidgetViewModel
|
||||||
{
|
{
|
||||||
public IViewModelTemplate Template => template;
|
public IViewModelTemplate Template => template;
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ namespace Hyperbar.Widget.MediaController.Windows;
|
|||||||
|
|
||||||
public partial class MediaInformationViewModel(IServiceProvider serviceProvider,
|
public partial class MediaInformationViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
WidgetComponentViewModel(serviceProvider, serviceFactory, mediator, disposer),
|
WidgetComponentViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer),
|
||||||
INotificationHandler<Changed<MediaInformation>>
|
INotificationHandler<Changed<MediaInformation>>
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
@@ -32,5 +33,5 @@ public partial class MediaInformationViewModel(IServiceProvider serviceProvider,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override async Task InitializeAsync() =>
|
public override async Task InitializeAsync() =>
|
||||||
await Mediator.PublishAsync<Request<MediaInformation>>();
|
await Publisher.PublishAsync<Request<MediaInformation>>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using Hyperbar.Widget;
|
namespace Hyperbar.Widget.Primary.Windows;
|
||||||
|
|
||||||
namespace Hyperbar.Widget.Primary.Windows;
|
public class PrimaryWidgetConfigurationHandler(IPublisher publisher,
|
||||||
|
|
||||||
public class PrimaryWidgetConfigurationHandler(IMediator mediator,
|
|
||||||
PrimaryWidgetConfiguration configuration,
|
PrimaryWidgetConfiguration configuration,
|
||||||
IFactory<PrimaryCommandConfiguration, IWidgetComponentViewModel?> factory,
|
IFactory<PrimaryCommandConfiguration, IWidgetComponentViewModel?> factory,
|
||||||
IProvider<PrimaryCommandConfiguration, IWidgetComponentViewModel?> provider,
|
IProvider<PrimaryCommandConfiguration, IWidgetComponentViewModel?> provider,
|
||||||
@@ -44,7 +42,7 @@ public class PrimaryWidgetConfigurationHandler(IMediator mediator,
|
|||||||
if (moved.Value is PrimaryCommandConfiguration configuration &&
|
if (moved.Value is PrimaryCommandConfiguration configuration &&
|
||||||
provider.Get(configuration) is IWidgetComponentViewModel viewModel)
|
provider.Get(configuration) is IWidgetComponentViewModel viewModel)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Move<IWidgetComponentViewModel>(configuration.Order, viewModel),
|
await publisher.PublishAsync(new Move<IWidgetComponentViewModel>(configuration.Order, viewModel),
|
||||||
moved.Key.ParentId == Guid.Empty ? nameof(PrimaryWidgetViewModel) : moved.Key.ParentId,
|
moved.Key.ParentId == Guid.Empty ? nameof(PrimaryWidgetViewModel) : moved.Key.ParentId,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
@@ -61,8 +59,7 @@ public class PrimaryWidgetConfigurationHandler(IMediator mediator,
|
|||||||
if (added.Value is PrimaryCommandConfiguration configuration &&
|
if (added.Value is PrimaryCommandConfiguration configuration &&
|
||||||
factory.Create(configuration) is IWidgetComponentViewModel viewModel)
|
factory.Create(configuration) is IWidgetComponentViewModel viewModel)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(
|
await publisher.PublishAsync(new Insert<IWidgetComponentViewModel>(configuration.Order, viewModel),
|
||||||
new Insert<IWidgetComponentViewModel>(configuration.Order, viewModel),
|
|
||||||
added.Key.ParentId == Guid.Empty ? nameof(PrimaryWidgetViewModel) : added.Key.ParentId,
|
added.Key.ParentId == Guid.Empty ? nameof(PrimaryWidgetViewModel) : added.Key.ParentId,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
@@ -78,8 +75,7 @@ public class PrimaryWidgetConfigurationHandler(IMediator mediator,
|
|||||||
if (removed.Value is PrimaryCommandConfiguration configuration &&
|
if (removed.Value is PrimaryCommandConfiguration configuration &&
|
||||||
provider.Get(configuration) is IWidgetComponentViewModel viewModel)
|
provider.Get(configuration) is IWidgetComponentViewModel viewModel)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(
|
await publisher.PublishAsync(new Remove<IWidgetComponentViewModel>(viewModel),
|
||||||
new Remove<IWidgetComponentViewModel>(viewModel),
|
|
||||||
removed.Key.ParentId == Guid.Empty ? nameof(PrimaryWidgetViewModel) : removed.Key.ParentId,
|
removed.Key.ParentId == Guid.Empty ? nameof(PrimaryWidgetViewModel) : removed.Key.ParentId,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ namespace Hyperbar.Widget.Primary.Windows;
|
|||||||
[NotificationHandler(nameof(PrimaryWidgetViewModel))]
|
[NotificationHandler(nameof(PrimaryWidgetViewModel))]
|
||||||
public class PrimaryWidgetViewModel(IServiceProvider serviceProvider,
|
public class PrimaryWidgetViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
ObservableCollectionViewModel<IWidgetComponentViewModel>(serviceProvider, serviceFactory, mediator, disposer),
|
ObservableCollectionViewModel<IWidgetComponentViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer),
|
||||||
IWidgetViewModel;
|
IWidgetViewModel;
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
using Hyperbar.Widget;
|
namespace Hyperbar.Widget.Primary.Windows;
|
||||||
|
|
||||||
namespace Hyperbar.Widget.Primary.Windows;
|
|
||||||
|
|
||||||
public class WidgetComponentViewModelEnumerator(PrimaryWidgetConfiguration configuration,
|
public class WidgetComponentViewModelEnumerator(PrimaryWidgetConfiguration configuration,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IFactory<PrimaryCommandConfiguration, IWidgetComponentViewModel?> factory,
|
IFactory<PrimaryCommandConfiguration, IWidgetComponentViewModel?> factory,
|
||||||
ICache<(Guid ParentId, Guid Id), PrimaryCommandConfiguration> cache) :
|
ICache<(Guid ParentId, Guid Id), PrimaryCommandConfiguration> cache) :
|
||||||
INotificationHandler<Enumerate<IWidgetComponentViewModel>>
|
INotificationHandler<Enumerate<IWidgetComponentViewModel>>
|
||||||
{
|
{
|
||||||
public async Task Handle(Enumerate<IWidgetComponentViewModel> notification, CancellationToken cancellationToken)
|
public async Task Handle(Enumerate<IWidgetComponentViewModel> notification,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Stack<(Guid, List<PrimaryCommandConfiguration>)> stack = new();
|
Stack<(Guid, List<PrimaryCommandConfiguration>)> stack = new();
|
||||||
stack.Push((Guid.Empty, configuration.Commands));
|
stack.Push((Guid.Empty, configuration.Commands));
|
||||||
@@ -30,7 +29,7 @@ public class WidgetComponentViewModelEnumerator(PrimaryWidgetConfiguration confi
|
|||||||
{
|
{
|
||||||
if (factory.Create(item) is IWidgetComponentViewModel viewModel)
|
if (factory.Create(item) is IWidgetComponentViewModel viewModel)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Create<IWidgetComponentViewModel>(viewModel), nameof(PrimaryWidgetViewModel),
|
await publisher.PublishAsync(new Create<IWidgetComponentViewModel>(viewModel), nameof(PrimaryWidgetViewModel),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ namespace Hyperbar.Widget;
|
|||||||
[NotificationHandler(nameof(Id))]
|
[NotificationHandler(nameof(Id))]
|
||||||
public partial class WidgetButtonViewModel(IServiceProvider serviceProvider,
|
public partial class WidgetButtonViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
Guid id,
|
Guid id,
|
||||||
string? text = null,
|
string? text = null,
|
||||||
string? icon = null,
|
string? icon = null,
|
||||||
RelayCommand? invokeCommand = null) : WidgetComponentViewModel(serviceProvider, serviceFactory, mediator, disposer)
|
RelayCommand? invokeCommand = null) : WidgetComponentViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? icon = icon;
|
private string? icon = icon;
|
||||||
|
|||||||
@@ -6,17 +6,19 @@ public partial class WidgetComponentViewModel :
|
|||||||
{
|
{
|
||||||
public WidgetComponentViewModel(IServiceProvider serviceProvider,
|
public WidgetComponentViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IEnumerable<IWidgetComponentViewModel> items) : base(serviceProvider, serviceFactory, mediator, disposer, items)
|
IEnumerable<IWidgetComponentViewModel> items) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer, items)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WidgetComponentViewModel(IServiceProvider serviceProvider,
|
public WidgetComponentViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IDisposer disposer) : base(serviceProvider, serviceFactory, mediator, disposer)
|
ISubscriber subscriber,
|
||||||
|
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Hyperbar.Widget;
|
|||||||
|
|
||||||
public class WidgetExtensionEnumerator(IFactory<Type, IWidget> factory,
|
public class WidgetExtensionEnumerator(IFactory<Type, IWidget> factory,
|
||||||
IHostEnvironment hostEnvironment,
|
IHostEnvironment hostEnvironment,
|
||||||
IMediator mediator) :
|
IPublisher publisher) :
|
||||||
INotificationHandler<Enumerate<WidgetExtension>>
|
INotificationHandler<Enumerate<WidgetExtension>>
|
||||||
{
|
{
|
||||||
public Task Handle(Enumerate<WidgetExtension> args,
|
public Task Handle(Enumerate<WidgetExtension> args,
|
||||||
@@ -29,7 +29,7 @@ public class WidgetExtensionEnumerator(IFactory<Type, IWidget> factory,
|
|||||||
{
|
{
|
||||||
if (factory.Create(widgetType) is IWidget widget)
|
if (factory.Create(widgetType) is IWidget widget)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Create<WidgetExtension>(new WidgetExtension(widget,
|
await publisher.PublishAsync(new Create<WidgetExtension>(new WidgetExtension(widget,
|
||||||
new WidgetAssembly(assembly))), cancellationToken);
|
new WidgetAssembly(assembly))), cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace Hyperbar.Widget;
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
public class WidgetExtensionHandler(IServiceProvider provider,
|
public class WidgetExtensionHandler(IServiceProvider provider,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IProxyServiceCollection<IWidgetBuilder> typedServices) :
|
IProxyServiceCollection<IWidgetBuilder> typedServices) :
|
||||||
INotificationHandler<Create<WidgetExtension>>
|
INotificationHandler<Create<WidgetExtension>>
|
||||||
{
|
{
|
||||||
@@ -22,7 +22,7 @@ public class WidgetExtensionHandler(IServiceProvider provider,
|
|||||||
});
|
});
|
||||||
|
|
||||||
IWidgetHost host = builder.Build();
|
IWidgetHost host = builder.Build();
|
||||||
await mediator.PublishAsync(new Create<IWidgetHost>(host),
|
await publisher.PublishAsync(new Create<IWidgetHost>(host),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
namespace Hyperbar.Widget;
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
public class WidgetExtensionInitializer(IMediator mediator) :
|
public class WidgetExtensionInitializer(IPublisher publisher) :
|
||||||
IInitializer
|
IInitializer
|
||||||
{
|
{
|
||||||
public async Task InitializeAsync() =>
|
public async Task InitializeAsync() =>
|
||||||
await mediator.PublishAsync<Enumerate<WidgetExtension>>();
|
await publisher.PublishAsync<Enumerate<WidgetExtension>>();
|
||||||
}
|
}
|
||||||
@@ -7,17 +7,17 @@ public sealed class WidgetHost :
|
|||||||
IWidgetHost
|
IWidgetHost
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider services;
|
private readonly IServiceProvider services;
|
||||||
private readonly IMediator mediator;
|
private readonly IPublisher publisher;
|
||||||
private readonly IProxyService<IMediator> proxyMediator;
|
private readonly IProxyService<IMediator> proxyMediator;
|
||||||
private readonly IEnumerable<IHostedService> hostedServices;
|
private readonly IEnumerable<IHostedService> hostedServices;
|
||||||
|
|
||||||
public WidgetHost(IServiceProvider services,
|
public WidgetHost(IServiceProvider services,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IProxyService<IMediator> proxyMediator,
|
IProxyService<IMediator> proxyMediator,
|
||||||
IEnumerable<IHostedService> hostedServices)
|
IEnumerable<IHostedService> hostedServices)
|
||||||
{
|
{
|
||||||
this.services = services;
|
this.services = services;
|
||||||
this.mediator = mediator;
|
this.publisher = publisher;
|
||||||
this.proxyMediator = proxyMediator;
|
this.proxyMediator = proxyMediator;
|
||||||
this.hostedServices = hostedServices;
|
this.hostedServices = hostedServices;
|
||||||
}
|
}
|
||||||
@@ -41,11 +41,11 @@ public sealed class WidgetHost :
|
|||||||
|
|
||||||
if (proxyMediator.Proxy is IMediator mediator)
|
if (proxyMediator.Proxy is IMediator mediator)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Started<IWidgetHost>(this),
|
await publisher.PublishAsync(new Started<IWidgetHost>(this),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.mediator.PublishAsync(new Started<IWidgetHost>(this),
|
await this.publisher.PublishAsync(new Started<IWidgetHost>(this),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ namespace Hyperbar.Widget;
|
|||||||
[NotificationHandler(nameof(Id))]
|
[NotificationHandler(nameof(Id))]
|
||||||
public partial class WidgetMenuViewModel(IServiceProvider serviceProvider,
|
public partial class WidgetMenuViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
Guid id = default,
|
Guid id = default,
|
||||||
string? text = null,
|
string? text = null,
|
||||||
string? icon = null,
|
string? icon = null,
|
||||||
RelayCommand? command = null) : WidgetComponentViewModel(serviceProvider, serviceFactory, mediator, disposer)
|
RelayCommand? command = null) : WidgetComponentViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IRelayCommand? click = command;
|
private IRelayCommand? click = command;
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ namespace Hyperbar.Widget;
|
|||||||
[NotificationHandler(nameof(Id))]
|
[NotificationHandler(nameof(Id))]
|
||||||
public partial class WidgetSplitButtonViewModel(IServiceProvider serviceProvider,
|
public partial class WidgetSplitButtonViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IEnumerable<IWidgetComponentViewModel> items,
|
IEnumerable<IWidgetComponentViewModel> items,
|
||||||
Guid id = default,
|
Guid id = default,
|
||||||
string? text = null,
|
string? text = null,
|
||||||
string? icon = null,
|
string? icon = null,
|
||||||
RelayCommand? command = null) : WidgetComponentViewModel(serviceProvider, serviceFactory, mediator, disposer, items)
|
RelayCommand? command = null) : WidgetComponentViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, items)
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IRelayCommand? click = command;
|
private IRelayCommand? click = command;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Hyperbar.Widget;
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
public class WidgetStartedHandler(IMediator mediator) :
|
public class WidgetStartedHandler(IPublisher publisher) :
|
||||||
INotificationHandler<Started<IWidgetHost>>
|
INotificationHandler<Started<IWidgetHost>>
|
||||||
{
|
{
|
||||||
public async Task Handle(Started<IWidgetHost> notification,
|
public async Task Handle(Started<IWidgetHost> notification,
|
||||||
@@ -12,7 +12,7 @@ public class WidgetStartedHandler(IMediator mediator) :
|
|||||||
{
|
{
|
||||||
if (host.Services.GetService<IWidgetViewModel>() is IWidgetViewModel viewModel)
|
if (host.Services.GetService<IWidgetViewModel>() is IWidgetViewModel viewModel)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Create<IWidgetViewModel>(viewModel),
|
await publisher.PublishAsync(new Create<IWidgetViewModel>(viewModel),
|
||||||
nameof(IWidgetHostViewModel), cancellationToken);
|
nameof(IWidgetHostViewModel), cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace Hyperbar.Widget;
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
public class WidgetViewModelEnumerator(IWidgetHost host,
|
public class WidgetViewModelEnumerator(IWidgetHost host,
|
||||||
IMediator mediator) :
|
IPublisher publisher) :
|
||||||
INotificationHandler<Enumerate<IWidgetViewModel>>
|
INotificationHandler<Enumerate<IWidgetViewModel>>
|
||||||
{
|
{
|
||||||
public async Task Handle(Enumerate<IWidgetViewModel> notification,
|
public async Task Handle(Enumerate<IWidgetViewModel> notification,
|
||||||
@@ -13,7 +13,7 @@ public class WidgetViewModelEnumerator(IWidgetHost host,
|
|||||||
{
|
{
|
||||||
foreach (IWidgetViewModel viewModel in viewModels)
|
foreach (IWidgetViewModel viewModel in viewModels)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Create<IWidgetViewModel>(viewModel),
|
await publisher.PublishAsync(new Create<IWidgetViewModel>(viewModel),
|
||||||
nameof(IWidgetHostViewModel), cancellationToken);
|
nameof(IWidgetHostViewModel), cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,12 @@
|
|||||||
<Application
|
<Application
|
||||||
x:Class="Hyperbar.Windows.App"
|
x:Class="Hyperbar.Windows.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
xmlns:ui="using:Hyperbar.UI.Windows">
|
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
<DataTemplate x:Key="DefaultDataTemplate">
|
|
||||||
<ui:ViewModelTemplatePresenter />
|
|
||||||
</DataTemplate>
|
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
||||||
@@ -10,8 +10,9 @@ public partial class ApplicationBarViewModel :
|
|||||||
public ApplicationBarViewModel(IViewModelTemplate template,
|
public ApplicationBarViewModel(IViewModelTemplate template,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IDisposer disposer) : base(serviceProvider, serviceFactory, mediator, disposer)
|
ISubscriber subscriber,
|
||||||
|
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
Template = template;
|
Template = template;
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
public class GeneralSettingsNavigationViewModel(IServiceProvider serviceProvider,
|
public class GeneralSettingsNavigationViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
string text) :
|
string text) :
|
||||||
NavigationViewModel(serviceProvider, serviceFactory, mediator, disposer, text)
|
NavigationViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, text)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -7,10 +7,11 @@ namespace Hyperbar.Widget;
|
|||||||
public partial class PrimaryViewModel(IViewModelTemplate template,
|
public partial class PrimaryViewModel(IViewModelTemplate template,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
int index) :
|
int index) :
|
||||||
ObservableCollectionViewModel<IWidgetViewModel>(serviceProvider, serviceFactory, mediator, disposer),
|
ObservableCollectionViewModel<IWidgetViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer),
|
||||||
IWidgetHostViewModel
|
IWidgetHostViewModel
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ public partial class SecondaryViewModel :
|
|||||||
public SecondaryViewModel(IViewModelTemplate template,
|
public SecondaryViewModel(IViewModelTemplate template,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
int index) : base(serviceProvider, serviceFactory, mediator, disposer)
|
int index) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
Template = template;
|
Template = template;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ namespace Hyperbar.Windows;
|
|||||||
public partial class SettingsButtonViewModel(IViewModelTemplate template,
|
public partial class SettingsButtonViewModel(IViewModelTemplate template,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
ObservableViewModel(serviceProvider, serviceFactory, mediator, disposer)
|
ObservableViewModel(serviceProvider, serviceFactory, publisher, disposer)
|
||||||
{
|
{
|
||||||
public IViewModelTemplate Template => template;
|
public IViewModelTemplate Template => template;
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,9 @@ public partial class SettingsViewModel :
|
|||||||
public SettingsViewModel(IViewModelTemplate template,
|
public SettingsViewModel(IViewModelTemplate template,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IDisposer disposer) : base(serviceProvider, serviceFactory, mediator, disposer)
|
ISubscriber subscriber,
|
||||||
|
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
Template = template;
|
Template = template;
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
public class WidgetNavigationViewModel(IServiceProvider serviceProvider,
|
public class WidgetNavigationViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
string text) :
|
string text) :
|
||||||
NavigationViewModel(serviceProvider, serviceFactory, mediator, disposer, text)
|
NavigationViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, text)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
public class WidgetSettingsNavigationViewModel(IServiceProvider serviceProvider,
|
public class WidgetSettingsNavigationViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
string text) :
|
string text) :
|
||||||
NavigationViewModel<WidgetNavigationViewModel>(serviceProvider, serviceFactory, mediator, disposer, text)
|
NavigationViewModel<WidgetNavigationViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer, text)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public class ConfigurationInitializer<TConfiguration>(IMediator mediator,
|
public class ConfigurationInitializer<TConfiguration>(IPublisher publisher,
|
||||||
IConfigurationMonitor<TConfiguration> monitor,
|
IConfigurationMonitor<TConfiguration> monitor,
|
||||||
IConfigurationReader<TConfiguration> reader,
|
IConfigurationReader<TConfiguration> reader,
|
||||||
IConfigurationWriter<TConfiguration> writer,
|
IConfigurationWriter<TConfiguration> writer,
|
||||||
@@ -21,7 +21,7 @@ public class ConfigurationInitializer<TConfiguration>(IMediator mediator,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await mediator.PublishAsync(new Changed<TConfiguration>(configuration));
|
await publisher.PublishAsync(new Changed<TConfiguration>(configuration));
|
||||||
await monitor.InitializeAsync();
|
await monitor.InitializeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
public class ConfigurationMonitor<TConfiguration>(IConfigurationFile<TConfiguration> configurationFile,
|
public class ConfigurationMonitor<TConfiguration>(IConfigurationFile<TConfiguration> configurationFile,
|
||||||
IConfigurationReader<TConfiguration> reader,
|
IConfigurationReader<TConfiguration> reader,
|
||||||
IMediator mediator) :
|
IPublisher publisher) :
|
||||||
IConfigurationMonitor<TConfiguration>
|
IConfigurationMonitor<TConfiguration>
|
||||||
where TConfiguration :
|
where TConfiguration :
|
||||||
class
|
class
|
||||||
@@ -16,7 +16,7 @@ public class ConfigurationMonitor<TConfiguration>(IConfigurationFile<TConfigurat
|
|||||||
{
|
{
|
||||||
if (reader.Read() is { } configuration)
|
if (reader.Read() is { } configuration)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Changed<TConfiguration>(configuration));
|
await publisher.PublishAsync(new Changed<TConfiguration>(configuration));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public class ConfigurationValueChangedNotification<TConfiguration, TValue>(IMediator mediator,
|
public class ConfigurationValueChangedNotification<TConfiguration, TValue>(IPublisher publisher,
|
||||||
Func<TConfiguration, Action<TValue>> factory) :
|
Func<TConfiguration, Action<TValue>> factory) :
|
||||||
IConfigurationValueChangedNotification<TConfiguration>
|
IConfigurationValueChangedNotification<TConfiguration>
|
||||||
where TConfiguration :
|
where TConfiguration :
|
||||||
@@ -18,7 +18,7 @@ public class ConfigurationValueChangedNotification<TConfiguration, TValue>(IMedi
|
|||||||
if (value is null || !value.Equals(newValue))
|
if (value is null || !value.Equals(newValue))
|
||||||
{
|
{
|
||||||
value = newValue;
|
value = newValue;
|
||||||
await mediator.PublishAsync(new Changed<TValue>(value));
|
await publisher.PublishAsync(new Changed<TValue>(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public static class IServiceCollectionExtensions
|
|||||||
class, new()
|
class, new()
|
||||||
{
|
{
|
||||||
services.AddSingleton<IConfigurationValueChangedNotification<TConfiguration>>(provider =>
|
services.AddSingleton<IConfigurationValueChangedNotification<TConfiguration>>(provider =>
|
||||||
new ConfigurationValueChangedNotification<TConfiguration, TValue>(provider.GetRequiredService<IMediator>(),
|
new ConfigurationValueChangedNotification<TConfiguration, TValue>(provider.GetRequiredService<IPublisher>(),
|
||||||
factory));
|
factory));
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
@@ -237,18 +237,6 @@ public static class IServiceCollectionExtensions
|
|||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static IServiceCollection AddNotificationRelay<TFromNotification,
|
|
||||||
TToNotification>(this IServiceCollection services)
|
|
||||||
where TFromNotification :
|
|
||||||
INotification
|
|
||||||
where TToNotification :
|
|
||||||
INotification, new()
|
|
||||||
{
|
|
||||||
return services.AddHandler<NotficationRelayHandler<TFromNotification,
|
|
||||||
TToNotification>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddRange(this IServiceCollection services,
|
public static IServiceCollection AddRange(this IServiceCollection services,
|
||||||
IServiceCollection fromServices)
|
IServiceCollection fromServices)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class AsyncLock(int initial = 1,
|
||||||
|
int maximum = 1) :
|
||||||
|
IDisposable
|
||||||
|
{
|
||||||
|
private readonly SemaphoreSlim semaphore = new(initial, maximum);
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
semaphore.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskAwaiter<AsyncLock> GetAwaiter() => LockAsync().GetAwaiter();
|
||||||
|
|
||||||
|
private async Task<AsyncLock> LockAsync()
|
||||||
|
{
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,24 +11,25 @@ public class Cache<TValue>(IDisposer disposer) :
|
|||||||
|
|
||||||
public void Add(TValue value)
|
public void Add(TValue value)
|
||||||
{
|
{
|
||||||
disposer.Add(value!, Disposable.Create(() =>
|
if (value is null)
|
||||||
{
|
{
|
||||||
Remove(value);
|
return;
|
||||||
}));
|
}
|
||||||
|
|
||||||
|
disposer.Add(value, Disposable.Create(() => Remove(value)));
|
||||||
cache.Add(value);
|
cache.Add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear() => cache.Clear();
|
public void Clear() => cache.Clear();
|
||||||
|
|
||||||
public System.Collections.Generic.IEnumerator<TValue> GetEnumerator() => cache.GetEnumerator();
|
public IEnumerator<TValue> GetEnumerator() => cache.GetEnumerator();
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
public bool Remove(TValue value) => cache.Remove(value);
|
public bool Remove(TValue value) => cache.Remove(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Cache<TKey, TValue>(IDisposer disposer) :
|
public class Cache<TKey, TValue> :
|
||||||
ICache<TKey, TValue>
|
ICache<TKey, TValue>
|
||||||
where TKey :
|
where TKey :
|
||||||
notnull
|
notnull
|
||||||
@@ -47,7 +48,7 @@ public class Cache<TKey, TValue>(IDisposer disposer) :
|
|||||||
|
|
||||||
public bool ContainsKey(TKey key) => cache.ContainsKey(key);
|
public bool ContainsKey(TKey key) => cache.ContainsKey(key);
|
||||||
|
|
||||||
public System.Collections.Generic.IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => cache.GetEnumerator();
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => cache.GetEnumerator();
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,9 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Disposables;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public class AsyncLock(int initial = 1,
|
|
||||||
int maximum = 1) : IDisposable
|
|
||||||
{
|
|
||||||
private readonly SemaphoreSlim semaphore = new(initial, maximum);
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
semaphore.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskAwaiter<AsyncLock> GetAwaiter() => LockAsync().GetAwaiter();
|
|
||||||
|
|
||||||
private async Task<AsyncLock> LockAsync()
|
|
||||||
{
|
|
||||||
await semaphore.WaitAsync();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class Disposer :
|
public class Disposer :
|
||||||
IDisposer
|
IDisposer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Hyperbar;
|
|
||||||
|
|
||||||
public interface IEnumerator<TItem>
|
|
||||||
{
|
|
||||||
IEnumerable<TItem?> Get();
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@ public interface IObservableViewModel :
|
|||||||
{
|
{
|
||||||
public IDisposer Disposer { get; }
|
public IDisposer Disposer { get; }
|
||||||
|
|
||||||
public IMediator Mediator { get; }
|
public IPublisher Publisher { get; }
|
||||||
|
|
||||||
public IServiceFactory ServiceFactory { get; }
|
public IServiceFactory ServiceFactory { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ namespace Hyperbar;
|
|||||||
public record Navigate(object Key) :
|
public record Navigate(object Key) :
|
||||||
INotification;
|
INotification;
|
||||||
|
|
||||||
public record Navigate<TTemplate>(TTemplate Template, object Content) :
|
public record Navigate<TView>(TView View, object ViewModel) :
|
||||||
INotification;
|
INotification;
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ public class NavigateHandler :
|
|||||||
{
|
{
|
||||||
private readonly IViewModelTemplateDescriptorProvider contentTemplateDescriptors;
|
private readonly IViewModelTemplateDescriptorProvider contentTemplateDescriptors;
|
||||||
private readonly IServiceProvider provider;
|
private readonly IServiceProvider provider;
|
||||||
private readonly IMediator mediator;
|
private readonly IPublisher publisher;
|
||||||
private readonly IEnumerable<INavigationDescriptor> navigationDescriptors;
|
private readonly IEnumerable<INavigationDescriptor> navigationDescriptors;
|
||||||
|
|
||||||
public NavigateHandler(IServiceProvider provider,
|
public NavigateHandler(IServiceProvider provider,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IEnumerable<INavigationDescriptor> navigationDescriptors,
|
IEnumerable<INavigationDescriptor> navigationDescriptors,
|
||||||
IViewModelTemplateDescriptorProvider contentTemplateDescriptors)
|
IViewModelTemplateDescriptorProvider contentTemplateDescriptors)
|
||||||
{
|
{
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.mediator = mediator;
|
this.publisher = publisher;
|
||||||
this.navigationDescriptors = navigationDescriptors;
|
this.navigationDescriptors = navigationDescriptors;
|
||||||
this.contentTemplateDescriptors = contentTemplateDescriptors;
|
this.contentTemplateDescriptors = contentTemplateDescriptors;
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ public class NavigateHandler :
|
|||||||
if (Activator.CreateInstance(navigateType,
|
if (Activator.CreateInstance(navigateType,
|
||||||
new object[] { template, content }) is object navigate)
|
new object[] { template, content }) is object navigate)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(navigate, cancellationToken);
|
await publisher.PublishAsync(navigate, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,29 +2,26 @@
|
|||||||
|
|
||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public partial class NavigationViewModel :
|
public partial class NavigationViewModel(IServiceProvider serviceProvider,
|
||||||
ObservableCollectionViewModel<INavigationViewModel>,
|
IServiceFactory serviceFactory,
|
||||||
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
|
IDisposer disposer,
|
||||||
|
string text) :
|
||||||
|
ObservableCollectionViewModel<INavigationViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer),
|
||||||
INavigationViewModel
|
INavigationViewModel
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? text;
|
private string? text = text;
|
||||||
|
|
||||||
public NavigationViewModel(IServiceProvider serviceProvider,
|
|
||||||
IServiceFactory serviceFactory,
|
|
||||||
IMediator mediator,
|
|
||||||
IDisposer disposer,
|
|
||||||
string text) : base(serviceProvider, serviceFactory, mediator, disposer)
|
|
||||||
{
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class NavigationViewModel<TNavigationViewModel>(IServiceProvider serviceProvider,
|
public partial class NavigationViewModel<TNavigationViewModel>(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
string text) :
|
string text) :
|
||||||
ObservableCollectionViewModel<TNavigationViewModel>(serviceProvider, serviceFactory, mediator, disposer),
|
ObservableCollectionViewModel<TNavigationViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer),
|
||||||
INavigationViewModel
|
INavigationViewModel
|
||||||
where TNavigationViewModel :
|
where TNavigationViewModel :
|
||||||
INavigationViewModel
|
INavigationViewModel
|
||||||
|
|||||||
@@ -27,31 +27,33 @@ public partial class ObservableCollectionViewModel<TViewModel> :
|
|||||||
|
|
||||||
public ObservableCollectionViewModel(IServiceProvider serviceProvider,
|
public ObservableCollectionViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer)
|
IDisposer disposer)
|
||||||
{
|
{
|
||||||
ServiceProvider = serviceProvider;
|
ServiceProvider = serviceProvider;
|
||||||
ServiceFactory = serviceFactory;
|
ServiceFactory = serviceFactory;
|
||||||
Mediator = mediator;
|
Publisher = publisher;
|
||||||
Disposer = disposer;
|
Disposer = disposer;
|
||||||
|
|
||||||
mediator.Subscribe(this);
|
subscriber.Add(this);
|
||||||
|
|
||||||
collection.CollectionChanged += OnCollectionChanged;
|
collection.CollectionChanged += OnCollectionChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollectionViewModel(IServiceProvider serviceProvider,
|
public ObservableCollectionViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IEnumerable<TViewModel> items)
|
IEnumerable<TViewModel> items)
|
||||||
{
|
{
|
||||||
ServiceProvider = serviceProvider;
|
ServiceProvider = serviceProvider;
|
||||||
ServiceFactory = serviceFactory;
|
ServiceFactory = serviceFactory;
|
||||||
Mediator = mediator;
|
Publisher = publisher;
|
||||||
Disposer = disposer;
|
Disposer = disposer;
|
||||||
|
|
||||||
mediator.Subscribe(this);
|
subscriber.Add(this);
|
||||||
|
|
||||||
collection.CollectionChanged += OnCollectionChanged;
|
collection.CollectionChanged += OnCollectionChanged;
|
||||||
AddRange(items);
|
AddRange(items);
|
||||||
@@ -74,14 +76,14 @@ public partial class ObservableCollectionViewModel<TViewModel> :
|
|||||||
|
|
||||||
bool ICollection.IsSynchronized => false;
|
bool ICollection.IsSynchronized => false;
|
||||||
|
|
||||||
public IMediator Mediator { get; private set; }
|
public IPublisher Publisher { get; private set; }
|
||||||
|
|
||||||
public IServiceFactory ServiceFactory { get; private set; }
|
public IServiceFactory ServiceFactory { get; private set; }
|
||||||
|
|
||||||
object ICollection.SyncRoot => this;
|
|
||||||
|
|
||||||
public IServiceProvider ServiceProvider { get; private set; }
|
public IServiceProvider ServiceProvider { get; private set; }
|
||||||
|
|
||||||
|
object ICollection.SyncRoot => this;
|
||||||
|
|
||||||
public TViewModel this[int index]
|
public TViewModel this[int index]
|
||||||
{
|
{
|
||||||
get => collection[index];
|
get => collection[index];
|
||||||
@@ -374,7 +376,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
|
|||||||
|
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
|
|
||||||
await Mediator.PublishAsync<Enumerate<TViewModel>>();
|
await Publisher.PublishAsync<Enumerate<TViewModel>>();
|
||||||
await InitializeAsync();
|
await InitializeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,6 +386,7 @@ public partial class ObservableCollectionViewModel<TViewModel> :
|
|||||||
|
|
||||||
public class ObservableCollectionViewModel(IServiceProvider serviceProvider,
|
public class ObservableCollectionViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
|
ISubscriber subscriber,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
ObservableCollectionViewModel<IDisposable>(serviceProvider, serviceFactory, mediator, disposer);
|
ObservableCollectionViewModel<IDisposable>(serviceProvider, serviceFactory, publisher, subscriber, disposer);
|
||||||
@@ -6,7 +6,7 @@ namespace Hyperbar;
|
|||||||
|
|
||||||
public class ObservableViewModel(IServiceProvider serviceProvider,
|
public class ObservableViewModel(IServiceProvider serviceProvider,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IPublisher publisher,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
ObservableObject,
|
ObservableObject,
|
||||||
IObservableViewModel
|
IObservableViewModel
|
||||||
@@ -18,7 +18,7 @@ public class ObservableViewModel(IServiceProvider serviceProvider,
|
|||||||
public ICommand InitializeCommand =>
|
public ICommand InitializeCommand =>
|
||||||
new AsyncRelayCommand(CoreInitializeAsync);
|
new AsyncRelayCommand(CoreInitializeAsync);
|
||||||
|
|
||||||
public IMediator Mediator => mediator;
|
public IPublisher Publisher => publisher;
|
||||||
|
|
||||||
public IServiceFactory ServiceFactory => serviceFactory;
|
public IServiceFactory ServiceFactory => serviceFactory;
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,4 @@
|
|||||||
public delegate Task<TResponse> HandlerDelegate<TMessage, TResponse>(TMessage message,
|
public delegate Task<TResponse> HandlerDelegate<TMessage, TResponse>(TMessage message,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
where TMessage :
|
where TMessage :
|
||||||
notnull,
|
|
||||||
IMessage;
|
IMessage;
|
||||||
@@ -1,27 +1,25 @@
|
|||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public class HandlerWrapper<TRequest, TResponse>
|
public class HandlerWrapper<TMessage, TReply>(IHandler<TMessage, TReply> handler,
|
||||||
where TRequest :
|
IEnumerable<IPipelineBehavior<TMessage, TReply>> pipelineBehaviours)
|
||||||
class,
|
where TMessage : class, IRequest<TReply>
|
||||||
IRequest<TResponse>
|
|
||||||
{
|
{
|
||||||
private readonly HandlerDelegate<TRequest, TResponse> handler;
|
private readonly IEnumerable<IPipelineBehavior<TMessage, TReply>> pipelineBehaviours =
|
||||||
|
pipelineBehaviours.Reverse();
|
||||||
|
|
||||||
public HandlerWrapper(IHandler<TRequest, TResponse> concreteHandler,
|
public async Task<TReply> Handle(TMessage message, CancellationToken cancellationToken)
|
||||||
IEnumerable<IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours)
|
|
||||||
{
|
{
|
||||||
HandlerDelegate<TRequest, TResponse> handler = concreteHandler.Handle;
|
HandlerDelegate<TMessage, TReply> currentHandler = handler.Handle;
|
||||||
foreach (IPipelineBehavior<TRequest, TResponse>? pipeline in pipelineBehaviours.Reverse())
|
foreach (IPipelineBehavior<TMessage, TReply> behavior in pipelineBehaviours)
|
||||||
{
|
{
|
||||||
HandlerDelegate<TRequest, TResponse> handlerCopy = handler;
|
HandlerDelegate<TMessage, TReply> previousHandler = currentHandler;
|
||||||
IPipelineBehavior<TRequest, TResponse> pipelineCopy = pipeline;
|
currentHandler = async (msg, token) =>
|
||||||
|
{
|
||||||
handler = (TRequest message, CancellationToken cancellationToken) =>
|
return await behavior.Handle(msg, previousHandler, token);
|
||||||
pipelineCopy.Handle(message, handlerCopy, cancellationToken);
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handler = handler;
|
return await currentHandler(message, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken) => handler(request, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,41 +2,9 @@
|
|||||||
|
|
||||||
public interface IMediator
|
public interface IMediator
|
||||||
{
|
{
|
||||||
Task PublishAsync<TNotification>(TNotification notification,
|
|
||||||
object key,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
where TNotification :
|
|
||||||
INotification;
|
|
||||||
|
|
||||||
Task PublishAsync<TNotification>(object key,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
where TNotification :
|
|
||||||
INotification,
|
|
||||||
new();
|
|
||||||
|
|
||||||
Task PublishAsync<TNotification>(TNotification notification,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
where TNotification :
|
|
||||||
INotification;
|
|
||||||
|
|
||||||
Task PublishAsync(object notification,
|
|
||||||
CancellationToken cancellationToken = default);
|
|
||||||
|
|
||||||
Task PublishAsync(object notification,
|
|
||||||
Func<Func<Task>, Task> marshal,
|
|
||||||
object? key = null,
|
|
||||||
CancellationToken cancellationToken = default);
|
|
||||||
|
|
||||||
Task PublishAsync<TNotification>(CancellationToken cancellationToken = default)
|
|
||||||
where TNotification :
|
|
||||||
INotification,
|
|
||||||
new();
|
|
||||||
|
|
||||||
Task<TResponse?> SendAsync<TResponse>(IRequest<TResponse> request,
|
Task<TResponse?> SendAsync<TResponse>(IRequest<TResponse> request,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
Task<object?> SendAsync(object message, CancellationToken
|
Task<object?> SendAsync(object message, CancellationToken
|
||||||
cancellationToken = default);
|
cancellationToken = default);
|
||||||
|
|
||||||
void Subscribe(object handler);
|
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public interface INotification : IMessage;
|
public interface INotification :
|
||||||
|
IMessage;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IPublisher
|
||||||
|
{
|
||||||
|
Task PublishAsync<TNotification>(TNotification notification,
|
||||||
|
object key,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification;
|
||||||
|
|
||||||
|
Task PublishAsync<TNotification>(object key,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification,
|
||||||
|
new();
|
||||||
|
|
||||||
|
Task PublishAsync<TNotification>(TNotification notification,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification;
|
||||||
|
|
||||||
|
Task PublishAsync(object notification,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
Task PublishAsync(object notification,
|
||||||
|
Func<Func<Task>, Task> marshal,
|
||||||
|
object? key = null,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
Task PublishAsync<TNotification>(CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification,
|
||||||
|
new();
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface ISubscriber
|
||||||
|
{
|
||||||
|
void Remove(object subscriber);
|
||||||
|
|
||||||
|
void Add(object subscriber);
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface ISubscriptionManager
|
||||||
|
{
|
||||||
|
IEnumerable<object?> GetHandlers(Type notificationType, object key);
|
||||||
|
|
||||||
|
void Remove(object subscriber);
|
||||||
|
|
||||||
|
void Add(object subscriber);
|
||||||
|
}
|
||||||
@@ -1,91 +1,8 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
namespace Hyperbar;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Hyperbar;
|
public class Mediator(IServiceProvider provider) :
|
||||||
|
|
||||||
public class Mediator(IServiceProvider provider,
|
|
||||||
IDispatcher dispatcher) :
|
|
||||||
IMediator
|
IMediator
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<object, List<object>> handlers = [];
|
|
||||||
|
|
||||||
public Task PublishAsync<TNotification>(object key,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
where TNotification :
|
|
||||||
INotification,
|
|
||||||
new() => PublishAsync(new TNotification(), args => dispatcher.InvokeAsync(async () => await args()),
|
|
||||||
key, cancellationToken);
|
|
||||||
|
|
||||||
public Task PublishAsync<TNotification>(TNotification notification,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
where TNotification :
|
|
||||||
INotification
|
|
||||||
{
|
|
||||||
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()),
|
|
||||||
null, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task PublishAsync<TNotification>(TNotification notification,
|
|
||||||
object key,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
where TNotification :
|
|
||||||
INotification
|
|
||||||
{
|
|
||||||
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()),
|
|
||||||
key, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task PublishAsync(object notification,
|
|
||||||
Func<Func<Task>, Task> marshal,
|
|
||||||
object? key = null,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
Type notificationType = notification.GetType();
|
|
||||||
|
|
||||||
List<object?> handlers = provider.GetServices(typeof(INotificationHandler<>)
|
|
||||||
.MakeGenericType(notificationType)).ToList();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<object, List<object>> subscriber in this.handlers)
|
|
||||||
{
|
|
||||||
if (subscriber.Key.Equals($"{key?.ToString()}:{notificationType}"))
|
|
||||||
{
|
|
||||||
handlers.AddRange(subscriber.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (object? handler in handlers)
|
|
||||||
{
|
|
||||||
if (handler is not null)
|
|
||||||
{
|
|
||||||
Type? handlerType = handler.GetType();
|
|
||||||
MethodInfo? handleMethod = handlerType.GetMethod("Handle",
|
|
||||||
[notificationType, typeof(CancellationToken)]);
|
|
||||||
|
|
||||||
if (handleMethod is not null)
|
|
||||||
{
|
|
||||||
marshal(() => (Task)handleMethod.Invoke(handler, new object[] { notification,
|
|
||||||
cancellationToken })!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task PublishAsync<TNotification>(CancellationToken cancellationToken = default)
|
|
||||||
where TNotification :
|
|
||||||
INotification,
|
|
||||||
new() => PublishAsync(new TNotification(), args => dispatcher.InvokeAsync(async () => await args()),
|
|
||||||
null, cancellationToken);
|
|
||||||
|
|
||||||
public Task PublishAsync(object notification,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()),
|
|
||||||
null, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<TResponse?> SendAsync<TResponse>(IRequest<TResponse> request,
|
public Task<TResponse?> SendAsync<TResponse>(IRequest<TResponse> request,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
@@ -121,44 +38,4 @@ public class Mediator(IServiceProvider provider,
|
|||||||
|
|
||||||
return Task.FromResult<object?>(default);
|
return Task.FromResult<object?>(default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Subscribe(object handler)
|
|
||||||
{
|
|
||||||
Type handlerType = handler.GetType();
|
|
||||||
object? key = GetKeyFromHandler(handlerType, handler);
|
|
||||||
|
|
||||||
foreach (Type interfaceType in GetNotificationHandlerInterfaces(handlerType))
|
|
||||||
{
|
|
||||||
if (interfaceType.GetGenericArguments().FirstOrDefault() is Type argumentType)
|
|
||||||
{
|
|
||||||
handlers.AddOrUpdate($"{(key is not null ? $"{key}:" : "")}{argumentType}", new List<object> { handler }, (value, collection) =>
|
|
||||||
{
|
|
||||||
collection.Add(handler);
|
|
||||||
return collection;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private object? GetKeyFromHandler(Type handlerType, object handler)
|
|
||||||
{
|
|
||||||
if (handlerType.GetCustomAttribute<NotificationHandlerAttribute>() is NotificationHandlerAttribute attribute)
|
|
||||||
{
|
|
||||||
if (handlerType.GetProperty($"{attribute.Key}") is PropertyInfo property
|
|
||||||
&& property.GetValue(handler) is { } value)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return attribute.Key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<Type> GetNotificationHandlerInterfaces(Type handlerType) => handlerType.GetInterfaces()
|
|
||||||
.Where(interfaceType => interfaceType.IsGenericType && interfaceType
|
|
||||||
.GetGenericTypeDefinition() == typeof(INotificationHandler<>));
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
namespace Hyperbar;
|
|
||||||
|
|
||||||
public class NotficationRelayHandler<TFromNotification, ToNotification>(IMediator mediator) :
|
|
||||||
INotificationHandler<TFromNotification>,
|
|
||||||
IHandler
|
|
||||||
where TFromNotification :
|
|
||||||
INotification
|
|
||||||
where ToNotification :
|
|
||||||
INotification, new()
|
|
||||||
{
|
|
||||||
private readonly IMediator mediator = mediator;
|
|
||||||
|
|
||||||
public Task Handle(TFromNotification notification, CancellationToken cancellationToken) =>
|
|
||||||
mediator.PublishAsync<ToNotification>(cancellationToken);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class Publisher(ISubscriptionManager subscriptionManager,
|
||||||
|
IServiceProvider provider,
|
||||||
|
IDispatcher dispatcher) :
|
||||||
|
IPublisher
|
||||||
|
{
|
||||||
|
public Task PublishAsync<TNotification>(object key,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification,
|
||||||
|
new() => PublishAsync(new TNotification(), args => dispatcher.InvokeAsync(async () => await args()),
|
||||||
|
key, cancellationToken);
|
||||||
|
|
||||||
|
public Task PublishAsync<TNotification>(TNotification notification,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification
|
||||||
|
{
|
||||||
|
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()),
|
||||||
|
null, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task PublishAsync<TNotification>(TNotification notification,
|
||||||
|
object key,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification
|
||||||
|
{
|
||||||
|
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()),
|
||||||
|
key, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task PublishAsync(object notification,
|
||||||
|
Func<Func<Task>, Task> marshal,
|
||||||
|
object? key = null,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
Type notificationType = notification.GetType();
|
||||||
|
List<object?> handlers = provider.GetServices(typeof(INotificationHandler<>)
|
||||||
|
.MakeGenericType(notificationType)).ToList();
|
||||||
|
|
||||||
|
foreach (object? handler in subscriptionManager.GetHandlers(notificationType,
|
||||||
|
$"{key?.ToString()}:{notificationType}"))
|
||||||
|
{
|
||||||
|
handlers.Add(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (object? handler in handlers)
|
||||||
|
{
|
||||||
|
if (handler is not null)
|
||||||
|
{
|
||||||
|
Type? handlerType = handler.GetType();
|
||||||
|
MethodInfo? handleMethod = handlerType.GetMethod("Handle",
|
||||||
|
[notificationType, typeof(CancellationToken)]);
|
||||||
|
|
||||||
|
if (handleMethod is not null)
|
||||||
|
{
|
||||||
|
marshal(() => (Task)handleMethod.Invoke(handler, new object[] { notification,
|
||||||
|
cancellationToken })!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task PublishAsync<TNotification>(CancellationToken cancellationToken = default)
|
||||||
|
where TNotification :
|
||||||
|
INotification,
|
||||||
|
new() => PublishAsync(new TNotification(), args => dispatcher.InvokeAsync(async () => await args()),
|
||||||
|
null, cancellationToken);
|
||||||
|
|
||||||
|
public Task PublishAsync(object notification,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()),
|
||||||
|
null, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class Subscriber(ISubscriptionManager subscriptionManager) :
|
||||||
|
ISubscriber
|
||||||
|
{
|
||||||
|
public void Remove(object subscriber) =>
|
||||||
|
subscriptionManager.Remove(subscriber);
|
||||||
|
|
||||||
|
public void Add(object subscriber) =>
|
||||||
|
subscriptionManager.Add(subscriber);
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public record Subscription(object Handler);
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class SubscriptionManager :
|
||||||
|
ISubscriptionManager
|
||||||
|
{
|
||||||
|
private readonly ConcurrentDictionary<object, List<WeakReference>> subscriptions = new();
|
||||||
|
|
||||||
|
public IEnumerable<object?> GetHandlers(Type notificationType, object key)
|
||||||
|
{
|
||||||
|
if (subscriptions.TryGetValue($"{key?.ToString()}:{notificationType}",
|
||||||
|
out List<WeakReference>? subscribers))
|
||||||
|
{
|
||||||
|
foreach (WeakReference weakRef in subscribers.ToArray())
|
||||||
|
{
|
||||||
|
object? target = weakRef.Target;
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
yield return target;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subscribers.Remove(weakRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(object subscriber)
|
||||||
|
{
|
||||||
|
Type handlerType = subscriber.GetType();
|
||||||
|
object? key = GetKeyFromHandler(handlerType, subscriber);
|
||||||
|
foreach (Type interfaceType in GetHandlerInterfaces(handlerType))
|
||||||
|
{
|
||||||
|
if (interfaceType.GetGenericArguments().FirstOrDefault() is Type argumentType)
|
||||||
|
{
|
||||||
|
if (subscriptions.TryGetValue($"{(key is not null ? $"{key}:" : "")}{argumentType}", out List<WeakReference>? subscribers))
|
||||||
|
{
|
||||||
|
for (int i = subscribers.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (!subscribers[i].IsAlive || subscribers[i].Target == subscriber)
|
||||||
|
{
|
||||||
|
subscribers.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(object subscriber)
|
||||||
|
{
|
||||||
|
Type handlerType = subscriber.GetType();
|
||||||
|
object? key = GetKeyFromHandler(handlerType, subscriber);
|
||||||
|
foreach (Type interfaceType in GetHandlerInterfaces(handlerType))
|
||||||
|
{
|
||||||
|
if (interfaceType.GetGenericArguments().FirstOrDefault() is Type argumentType)
|
||||||
|
{
|
||||||
|
subscriptions.AddOrUpdate($"{(key is not null ? $"{key}:" : "")}{argumentType}", _ => new List<WeakReference> { new WeakReference(subscriber) }, (_, collection) =>
|
||||||
|
{
|
||||||
|
collection.Add(new WeakReference(subscriber));
|
||||||
|
return collection;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object? GetKeyFromHandler(Type handlerType, object handler)
|
||||||
|
{
|
||||||
|
if (handlerType.GetCustomAttribute<NotificationHandlerAttribute>() is NotificationHandlerAttribute attribute)
|
||||||
|
{
|
||||||
|
if (handlerType.GetProperty($"{attribute.Key}") is PropertyInfo property
|
||||||
|
&& property.GetValue(handler) is { } value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return attribute.Key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<Type> GetHandlerInterfaces(Type handlerType) =>
|
||||||
|
handlerType.GetInterfaces().Where(interfaceType => interfaceType.IsGenericType &&
|
||||||
|
interfaceType.GetGenericTypeDefinition() == typeof(INotificationHandler<>));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user