Skip to content

Commit

Permalink
add configurator for better extension control
Browse files Browse the repository at this point in the history
  • Loading branch information
aritchie committed Jun 3, 2024
1 parent 8aaa2c4 commit 4c264fc
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static MauiApp CreateMauiApp()
builder.Logging.AddDebug();
builder.Services.AddBlazorWebViewDeveloperTools();
#endif
builder.Services.AddShinyMediator<MauiEventCollector>();
builder.Services.AddShinyMediator(x => x.UseMaui());
builder.Services.AddSingletonAsImplementedInterfaces<SingletonEventHandler>();
builder.Services.AddSingletonAsImplementedInterfaces<SingletonRequestHandler>();

Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ First, let's install [Shiny.Mediator.Maui](https://www.nuget.org/packages/Shiny.
Now...let's go back to our MauiProgram.cs and alter the AddShinyMediator

```csharp
builder.Services.AddShinyMediator<MauiEventCollector>();
builder.Services.AddShinyMediator(cfg => cfg.UseMaui());
```

Now your viewmodel (or page) can simply implement the IEventHandler<T> interface to participate
Expand Down
5 changes: 5 additions & 0 deletions src/Shiny.Mediator.Maui/MauiEventCollector.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
namespace Shiny.Mediator;

public static class MauiEventCollectorExtensions
{
public static ShinyConfigurator UseMaui(this ShinyConfigurator cfg) => cfg.AddEventCollector<MauiEventCollector>();
}

public class MauiEventCollector : IEventCollector
{
public IReadOnlyList<IEventHandler<TEvent>> GetHandlers<TEvent>() where TEvent : IEvent
Expand Down
16 changes: 10 additions & 6 deletions src/Shiny.Mediator/MediatorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using Shiny.Mediator.Impl;
using Shiny.Mediator.Infrastructure;
using Shiny.Mediator.Middleware;

namespace Shiny.Mediator;

Expand All @@ -15,20 +16,23 @@ public static void RunOffThread(this Task task, Action<Exception> onError)
onError(x.Exception);
});

public static IServiceCollection AddShinyMediator(this IServiceCollection services)

public static IServiceCollection AddShinyMediator(this IServiceCollection services, Action<ShinyConfigurator>? configurator = null)
{
services.TryAddSingleton<IMediator, Impl.Mediator>();
services.TryAddSingleton<IRequestSender, DefaultRequestSender>();
services.TryAddSingleton<IEventPublisher, DefaultEventPublisher>();
configurator?.Invoke(new ShinyConfigurator(services));

return services;
}


public static IServiceCollection AddShinyMediator<TEventCollector>(this IServiceCollection services) where TEventCollector : class, IEventCollector
{
services.AddSingleton<IEventCollector, TEventCollector>();
return services.AddShinyMediator();
}
public static ShinyConfigurator AddExceptionHandling(this ShinyConfigurator cfg)
=> cfg.AddOpenRequestMiddleware(typeof(ExceptionHandlerMiddleware<,>));

public static ShinyConfigurator AddTimedMiddleware(this ShinyConfigurator cfg)
=> cfg.AddOpenRequestMiddleware(typeof(TimedMiddleware<,>));


public static IServiceCollection AddSingletonAsImplementedInterfaces<TImplementation>(this IServiceCollection services) where TImplementation : class
Expand Down
45 changes: 45 additions & 0 deletions src/Shiny.Mediator/ShinyConfigurator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Microsoft.Extensions.DependencyInjection;

namespace Shiny.Mediator;


public sealed class ShinyConfigurator(IServiceCollection services)
{
public ShinyConfigurator AddRequestMiddleware<TRequest, TResult, TImpl>(
ServiceLifetime lifetime = ServiceLifetime.Scoped)
where TRequest : IRequest<TResult>
where TImpl : class, IRequestMiddleware<TRequest, TResult>
{
switch (lifetime)
{
case ServiceLifetime.Transient:
services.AddTransient<IRequestMiddleware<TRequest, TResult>, TImpl>();
break;

case ServiceLifetime.Scoped:
services.AddScoped<IRequestMiddleware<TRequest, TResult>, TImpl>();
break;

case ServiceLifetime.Singleton:
services.AddSingleton<IRequestMiddleware<TRequest, TResult>, TImpl>();
break;
}

return this;
}


public ShinyConfigurator AddOpenRequestMiddleware(Type implementationType, ServiceLifetime lifetime = ServiceLifetime.Scoped)
{
// validate open generic
services.Add(new ServiceDescriptor(typeof(IRequestMiddleware<,>), null, implementationType, lifetime));
return this;
}


public ShinyConfigurator AddEventCollector<TImpl>() where TImpl : class, IEventCollector
{
services.AddSingleton<IEventCollector, TImpl>();
return this;
}
}
2 changes: 1 addition & 1 deletion tests/Shiny.Mediator.Tests/EventHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public EventHandlerTests()
public async Task SubscriptionFired()
{
var services = new ServiceCollection();
services.AddShinyMediator();
services.AddShinyMediator(cfg => {});
var sp = services.BuildServiceProvider();
var mediator = sp.GetRequiredService<IMediator>();

Expand Down
5 changes: 4 additions & 1 deletion tests/Shiny.Mediator.Tests/MiddlewareTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ public MiddlewareTests()
public async Task ConstrainedAndOpen(bool addConstrained, bool addOpen)
{
var services = new ServiceCollection();
services.AddShinyMediator();
services.AddShinyMediator(cfg =>
{

});
services.AddSingletonAsImplementedInterfaces<MiddlewareRequestResultHandler>();

if (addConstrained)
Expand Down
2 changes: 1 addition & 1 deletion tests/Shiny.Mediator.Tests/RequestHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public async Task Missing_RequestHandler()
try
{
var services = new ServiceCollection();
services.AddShinyMediator();
services.AddShinyMediator(cfg => { });
var sp = services.BuildServiceProvider();
var mediator = sp.GetRequiredService<IMediator>();
await mediator.Send(new TestRequest());
Expand Down
8 changes: 5 additions & 3 deletions tests/Shiny.Mediator.Tests/SourceGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ public class SourceGeneratorTests
public void DidRegister()
{
var services = new ServiceCollection();
services.AddShinyMediator();
// TODO: source gen call
// services.AddDiscoveredMediatorHandlers();
services.AddShinyMediator(cfg =>
{
// TODO: source gen call
// services.AddDiscoveredMediatorHandlers();
});
var sp = services.BuildServiceProvider();

sp.GetService<IEventHandler<SourceGenEvent>>().Should().NotBeNull("Event Handler not found");
Expand Down

0 comments on commit 4c264fc

Please sign in to comment.