Initial navigaiton work; opening Windows
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
|
||||||
|
namespace Hyperbar.UI.Windows;
|
||||||
|
|
||||||
|
public class WindowHandler :
|
||||||
|
INavigationHandler<Window>
|
||||||
|
{
|
||||||
|
public Task Handle(Navigate<Window> args,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (args.Template is Window window)
|
||||||
|
{
|
||||||
|
window.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,8 +9,8 @@ public class WidgetExtensionEnumerator(IFactory<Type, IWidget> factory,
|
|||||||
IMediator mediator) :
|
IMediator mediator) :
|
||||||
INotificationHandler<Enumerate<WidgetExtension>>
|
INotificationHandler<Enumerate<WidgetExtension>>
|
||||||
{
|
{
|
||||||
public Task Handle(Enumerate<WidgetExtension> notification,
|
public Task Handle(Enumerate<WidgetExtension> args,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
string extensionsDirectory = Path.Combine(hostEnvironment.ContentRootPath, "Extensions");
|
string extensionsDirectory = Path.Combine(hostEnvironment.ContentRootPath, "Extensions");
|
||||||
if (Directory.Exists(extensionsDirectory))
|
if (Directory.Exists(extensionsDirectory))
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using Microsoft.UI.Dispatching;
|
|||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Hyperbar.Widget.Windows;
|
using Hyperbar.Widget.Windows;
|
||||||
using Microsoft.UI.Xaml.Markup;
|
|
||||||
|
|
||||||
namespace Hyperbar.Windows;
|
namespace Hyperbar.Windows;
|
||||||
|
|
||||||
@@ -46,6 +45,8 @@ public partial class App :
|
|||||||
args.Placement = DesktopApplicationBarPlacemenet.Top;
|
args.Placement = DesktopApplicationBarPlacemenet.Top;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
services.AddNavigationHandler<WindowHandler>();
|
||||||
|
|
||||||
services.AddSingleton<DesktopApplicationBar>();
|
services.AddSingleton<DesktopApplicationBar>();
|
||||||
services.AddContentTemplate<ApplicationBarViewModel, ApplicationBarView>();
|
services.AddContentTemplate<ApplicationBarViewModel, ApplicationBarView>();
|
||||||
services.AddContentTemplate<PrimaryViewModel, PrimaryView>();
|
services.AddContentTemplate<PrimaryViewModel, PrimaryView>();
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ public partial class SecondaryViewModel :
|
|||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
int index) : base(serviceFactory, mediator, disposer)
|
int index) : base(serviceFactory, mediator, disposer)
|
||||||
{
|
{
|
||||||
|
TemplateFactory = templateFactory;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.TemplateFactory = templateFactory;
|
|
||||||
|
|
||||||
Add<SettingsButtonViewModel>();
|
Add<SettingsButtonViewModel>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
Width="{ThemeResource ButtonWidth}"
|
Width="{ThemeResource ButtonWidth}"
|
||||||
Height="{ThemeResource ButtonHeight}"
|
Height="{ThemeResource ButtonHeight}"
|
||||||
Padding="{ThemeResource ButtonPadding}"
|
Padding="{ThemeResource ButtonPadding}"
|
||||||
|
Command="{x:Bind ViewModel.InvokeCommand}"
|
||||||
Content=""
|
Content=""
|
||||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||||
FontSize="16" />
|
FontSize="16" />
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ using Microsoft.UI.Xaml.Controls;
|
|||||||
|
|
||||||
namespace Hyperbar.Windows;
|
namespace Hyperbar.Windows;
|
||||||
|
|
||||||
public sealed partial class SettingsButtonView :
|
public partial class SettingsButtonView :
|
||||||
UserControl
|
UserControl
|
||||||
{
|
{
|
||||||
public SettingsButtonView() =>
|
public SettingsButtonView() =>
|
||||||
this.InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
protected SettingsButtonViewModel ViewModel =>
|
||||||
|
(SettingsButtonViewModel)DataContext;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,24 @@
|
|||||||
namespace Hyperbar.Windows;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
|
||||||
public class SettingsButtonViewModel(ITemplateFactory templateFactory,
|
namespace Hyperbar.Windows;
|
||||||
IServiceFactory serviceFactory,
|
|
||||||
IMediator mediator,
|
public partial class SettingsButtonViewModel :
|
||||||
IDisposer disposer) :
|
ObservableViewModel,
|
||||||
ObservableViewModel(serviceFactory, mediator, disposer),
|
|
||||||
ITemplatedViewModel
|
ITemplatedViewModel
|
||||||
{
|
{
|
||||||
public ITemplateFactory TemplateFactory => templateFactory;
|
[ObservableProperty]
|
||||||
|
private IRelayCommand? invokeCommand;
|
||||||
|
|
||||||
|
public SettingsButtonViewModel(ITemplateFactory templateFactory,
|
||||||
|
IServiceFactory serviceFactory,
|
||||||
|
IMediator mediator,
|
||||||
|
IDisposer disposer) : base(serviceFactory, mediator, disposer)
|
||||||
|
{
|
||||||
|
TemplateFactory = templateFactory;
|
||||||
|
InvokeCommand = new AsyncRelayCommand(async () =>
|
||||||
|
await mediator.PublishAsync(new Navigate("Settings")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITemplateFactory TemplateFactory { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<UserControl
|
<Window
|
||||||
x:Class="Hyperbar.Windows.SettingsView"
|
x:Class="Hyperbar.Windows.SettingsView"
|
||||||
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">
|
||||||
<Grid />
|
<Button>afsdfdg</Button>
|
||||||
</UserControl>
|
</Window>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
namespace Hyperbar.Windows
|
namespace Hyperbar.Windows
|
||||||
{
|
{
|
||||||
public sealed partial class SettingsView :
|
public sealed partial class SettingsView :
|
||||||
UserControl
|
Window
|
||||||
{
|
{
|
||||||
public SettingsView() =>
|
public SettingsView() =>
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
|||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Microsoft.Extensions.FileProviders.Physical;
|
using Microsoft.Extensions.FileProviders.Physical;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Net.Mime;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
@@ -128,6 +130,26 @@ public static class IServiceCollectionExtensions
|
|||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddNavigationHandler<THandler>(this IServiceCollection services)
|
||||||
|
where THandler :
|
||||||
|
INavigationHandler,
|
||||||
|
IHandler
|
||||||
|
{
|
||||||
|
Type? contract = typeof(THandler).GetInterfaces()
|
||||||
|
.FirstOrDefault(t => t.Name == typeof(INavigationHandler<>).Name);
|
||||||
|
|
||||||
|
if (contract?.GetGenericArguments() is { Length: 1 } arguments)
|
||||||
|
{
|
||||||
|
services.AddTransient<INavigationDescriptor>(provider => new NavigationDescriptor
|
||||||
|
{
|
||||||
|
Type = arguments[0]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
services.AddHandler<THandler>();
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddContentTemplate<TContent, TTemplate>(this IServiceCollection services,
|
public static IServiceCollection AddContentTemplate<TContent, TTemplate>(this IServiceCollection services,
|
||||||
object? key = null)
|
object? key = null)
|
||||||
{
|
{
|
||||||
@@ -163,52 +185,59 @@ public static class IServiceCollectionExtensions
|
|||||||
|
|
||||||
services.AddSingleton<IDisposer, Disposer>();
|
services.AddSingleton<IDisposer, Disposer>();
|
||||||
|
|
||||||
|
services.AddHandler<NavigateHandler>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddHandler<THandler>(this IServiceCollection services,
|
public static IServiceCollection AddHandler<THandler>(
|
||||||
|
this IServiceCollection services,
|
||||||
ServiceLifetime lifetime = ServiceLifetime.Transient)
|
ServiceLifetime lifetime = ServiceLifetime.Transient)
|
||||||
where THandler :
|
where THandler : IHandler
|
||||||
IHandler
|
|
||||||
{
|
{
|
||||||
if (typeof(THandler).GetInterfaces() is { } contracts)
|
if (typeof(THandler).GetInterfaces() is { } contracts)
|
||||||
{
|
{
|
||||||
foreach (Type contract in contracts)
|
foreach (Type contract in contracts)
|
||||||
{
|
{
|
||||||
if (contract.Name == typeof(INotificationHandler<>).Name)
|
if (contract.Name == typeof(INotificationHandler<>).Name &&
|
||||||
|
contract.GetGenericArguments() is { Length: 1 } notificationArguments)
|
||||||
{
|
{
|
||||||
if (contract.GetGenericArguments() is { Length: 1 } arguments)
|
Type notificationType = notificationArguments[0];
|
||||||
{
|
services.Add(new ServiceDescriptor(
|
||||||
Type notificationType = arguments[0];
|
typeof(INotificationHandler<>).MakeGenericType(notificationType),
|
||||||
services.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType), typeof(THandler), lifetime));
|
typeof(THandler),
|
||||||
}
|
lifetime));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contract.Name == typeof(IHandler<,>).Name)
|
if (contract.Name == typeof(IHandler<,>).Name &&
|
||||||
|
contract.GetGenericArguments() is { Length: 2 } handlerArguments)
|
||||||
{
|
{
|
||||||
if (contract.GetGenericArguments() is { Length: 2 } arguments)
|
Type requestType = handlerArguments[0];
|
||||||
{
|
Type responseType = handlerArguments[1];
|
||||||
Type requestType = arguments[0];
|
|
||||||
Type responseType = arguments[1];
|
|
||||||
|
|
||||||
Type wrapperType = typeof(HandlerWrapper<,>).MakeGenericType(requestType, responseType);
|
Type wrapperType = typeof(HandlerWrapper<,>).MakeGenericType(requestType, responseType);
|
||||||
|
|
||||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||||
services.Add(new ServiceDescriptor(wrapperType,
|
services.Add(new ServiceDescriptor(
|
||||||
provider => provider.GetService<IServiceFactory>()?.Create(wrapperType,
|
wrapperType,
|
||||||
|
provider =>
|
||||||
|
provider.GetService<IServiceFactory>()?.Create(
|
||||||
|
wrapperType,
|
||||||
provider.GetRequiredService<THandler>(),
|
provider.GetRequiredService<THandler>(),
|
||||||
provider.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!,
|
provider.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType))
|
||||||
lifetime
|
)!,
|
||||||
));
|
lifetime
|
||||||
}
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static IServiceCollection AddNotificationRelay<TFromNotification,
|
public static IServiceCollection AddNotificationRelay<TFromNotification,
|
||||||
TToNotification>(this IServiceCollection services)
|
TToNotification>(this IServiceCollection services)
|
||||||
where TFromNotification :
|
where TFromNotification :
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface INavigationDescriptor
|
||||||
|
{
|
||||||
|
Type Type { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface INavigationHandler;
|
||||||
|
|
||||||
|
public interface INavigationHandler<TNavigation> :
|
||||||
|
INotificationHandler<Navigate<TNavigation>>,
|
||||||
|
INavigationHandler;
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public record Navigate(object Key) :
|
||||||
|
INotification;
|
||||||
|
|
||||||
|
public record Navigate<TTemplate>(TTemplate Template, object Content) :
|
||||||
|
INotification;
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class NavigateHandler :
|
||||||
|
INotificationHandler<Navigate>
|
||||||
|
{
|
||||||
|
private readonly IEnumerable<IContentTemplateDescriptor> contentTemplateDescriptors;
|
||||||
|
private readonly IServiceProvider provider;
|
||||||
|
private readonly IMediator mediator;
|
||||||
|
private readonly IEnumerable<INavigationDescriptor> navigationDescriptors;
|
||||||
|
|
||||||
|
public NavigateHandler(IServiceProvider provider,
|
||||||
|
IMediator mediator,
|
||||||
|
IEnumerable<INavigationDescriptor> navigationDescriptors,
|
||||||
|
IEnumerable<IContentTemplateDescriptor> contentTemplateDescriptors)
|
||||||
|
{
|
||||||
|
this.provider = provider;
|
||||||
|
this.mediator = mediator;
|
||||||
|
this.navigationDescriptors = navigationDescriptors;
|
||||||
|
this.contentTemplateDescriptors = contentTemplateDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Handle(Navigate args,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (contentTemplateDescriptors.FirstOrDefault(x => x.Key == args.Key)
|
||||||
|
is IContentTemplateDescriptor contentTemplateDescriptor)
|
||||||
|
{
|
||||||
|
if (navigationDescriptors.FirstOrDefault(x => contentTemplateDescriptor.TemplateType == x.Type ||
|
||||||
|
contentTemplateDescriptor.TemplateType.BaseType == x.Type) is { } navigationDescriptor)
|
||||||
|
{
|
||||||
|
if (contentTemplateDescriptor.TemplateType == navigationDescriptor.Type ||
|
||||||
|
contentTemplateDescriptor.TemplateType.BaseType == navigationDescriptor.Type)
|
||||||
|
{
|
||||||
|
if (provider.GetRequiredKeyedService(contentTemplateDescriptor.TemplateType,
|
||||||
|
contentTemplateDescriptor.Key) is { } template)
|
||||||
|
{
|
||||||
|
Type navigateType = typeof(Navigate<>)
|
||||||
|
.MakeGenericType(navigationDescriptor.Type);
|
||||||
|
|
||||||
|
if (Activator.CreateInstance(navigateType,
|
||||||
|
new object[] { template, args.Key }) is object navigate)
|
||||||
|
{
|
||||||
|
await mediator.PublishAsync(navigate, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public record NavigationDescriptor :
|
||||||
|
INavigationDescriptor
|
||||||
|
{
|
||||||
|
public required Type Type { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,36 +1,5 @@
|
|||||||
|
|
||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public record Remove<TValue>(TValue Value) : INotification;
|
public record Remove<TValue>(TValue Value) :
|
||||||
|
INotification;
|
||||||
public record Navigate(object Key) :
|
|
||||||
INotification;
|
|
||||||
|
|
||||||
public class NavigateHandler :
|
|
||||||
INotificationHandler<Navigate>
|
|
||||||
{
|
|
||||||
private readonly IEnumerable<IContentTemplateDescriptor> descriptors;
|
|
||||||
|
|
||||||
public NavigateHandler(IEnumerable<IContentTemplateDescriptor> descriptors,
|
|
||||||
IServiceProvider provider)
|
|
||||||
{
|
|
||||||
this.descriptors = descriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task Handle(Navigate args,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (descriptors.FirstOrDefault(x => x.Key == args.Key)
|
|
||||||
is IContentTemplateDescriptor descriptor)
|
|
||||||
{
|
|
||||||
//if (provider.GetRequiredKeyedService(descriptor.TemplateType,
|
|
||||||
// descriptor.Key) is { } template)
|
|
||||||
//{
|
|
||||||
// return template;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -19,12 +19,13 @@ public interface IMediator
|
|||||||
where TNotification :
|
where TNotification :
|
||||||
INotification;
|
INotification;
|
||||||
|
|
||||||
Task PublishAsync<TNotification>(TNotification notification,
|
Task PublishAsync(object notification,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
Task PublishAsync(object notification,
|
||||||
Func<Func<Task>, Task> marshal,
|
Func<Func<Task>, Task> marshal,
|
||||||
object? key = null,
|
object? key = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default);
|
||||||
where TNotification :
|
|
||||||
INotification;
|
|
||||||
|
|
||||||
Task PublishAsync<TNotification>(CancellationToken cancellationToken = default)
|
Task PublishAsync<TNotification>(CancellationToken cancellationToken = default)
|
||||||
where TNotification :
|
where TNotification :
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ public interface INotificationHandler<in TNotification> :
|
|||||||
INotification
|
INotification
|
||||||
{
|
{
|
||||||
Task Handle(TNotification args,
|
Task Handle(TNotification args,
|
||||||
CancellationToken cancellationToken);
|
CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ public class Mediator(IServiceProvider provider,
|
|||||||
IDispatcher dispatcher) :
|
IDispatcher dispatcher) :
|
||||||
IMediator
|
IMediator
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<object, List<dynamic>> subscriptions = [];
|
private readonly ConcurrentDictionary<object, List<object>> handlers = [];
|
||||||
|
|
||||||
public Task PublishAsync<TNotification>(object key,
|
public Task PublishAsync<TNotification>(object key,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
@@ -36,30 +36,38 @@ public class Mediator(IServiceProvider provider,
|
|||||||
key, cancellationToken);
|
key, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task PublishAsync<TNotification>(TNotification notification,
|
public Task PublishAsync(object notification,
|
||||||
Func<Func<Task>, Task> marshal,
|
Func<Func<Task>, Task> marshal,
|
||||||
object? key = null,
|
object? key = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
where TNotification :
|
|
||||||
INotification
|
|
||||||
{
|
{
|
||||||
List<INotificationHandler<TNotification>> handlers =
|
Type notificationType = notification.GetType();
|
||||||
provider.GetServices<INotificationHandler<TNotification>>().ToList();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<object, List<dynamic>> subscriber in subscriptions)
|
List<object?> handlers = provider.GetServices(typeof(INotificationHandler<>)
|
||||||
|
.MakeGenericType(notificationType)).ToList();
|
||||||
|
|
||||||
|
foreach (KeyValuePair<object, List<object>> subscriber in this.handlers)
|
||||||
{
|
{
|
||||||
if (subscriber.Key.Equals($"{(key is not null ? $"{key}:" : "")}{typeof(TNotification)}"))
|
if (subscriber.Key.Equals($"{key?.ToString()}:{notificationType}"))
|
||||||
{
|
{
|
||||||
foreach (dynamic handler in subscriber.Value)
|
handlers.AddRange(subscriber.Value);
|
||||||
{
|
|
||||||
handlers.Add(handler);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (INotificationHandler<TNotification> handler in handlers)
|
foreach (object? handler in handlers)
|
||||||
{
|
{
|
||||||
marshal(() => handler.Handle(notification, cancellationToken));
|
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;
|
return Task.CompletedTask;
|
||||||
@@ -71,6 +79,13 @@ public class Mediator(IServiceProvider provider,
|
|||||||
new() => PublishAsync(new TNotification(), args => dispatcher.InvokeAsync(async () => await args()),
|
new() => PublishAsync(new TNotification(), args => dispatcher.InvokeAsync(async () => await args()),
|
||||||
null, cancellationToken);
|
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)
|
||||||
{
|
{
|
||||||
@@ -116,7 +131,7 @@ public class Mediator(IServiceProvider provider,
|
|||||||
{
|
{
|
||||||
if (interfaceType.GetGenericArguments().FirstOrDefault() is Type argumentType)
|
if (interfaceType.GetGenericArguments().FirstOrDefault() is Type argumentType)
|
||||||
{
|
{
|
||||||
subscriptions.AddOrUpdate($"{(key is not null ? $"{key}:" : "")}{argumentType}", new List<object> { handler }, (value, collection) =>
|
handlers.AddOrUpdate($"{(key is not null ? $"{key}:" : "")}{argumentType}", new List<object> { handler }, (value, collection) =>
|
||||||
{
|
{
|
||||||
collection.Add(handler);
|
collection.Add(handler);
|
||||||
return collection;
|
return collection;
|
||||||
|
|||||||
Reference in New Issue
Block a user