Skip to content

Commit

Permalink
feat: allow scoped registrations
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardSmit committed Dec 21, 2023
1 parent c93f8af commit 0e94449
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 84 deletions.
24 changes: 12 additions & 12 deletions src/Mediator.DependencyInjection/Builder/MediatorBuilder.Default.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,39 @@ namespace Zapto.Mediator;

public partial class MediatorBuilder : IMediatorBuilder
{
public IMediatorBuilder AddDefaultRequestHandler(Type handlerType)
public IMediatorBuilder AddDefaultRequestHandler(Type handlerType, RegistrationScope scope = RegistrationScope.Transient)
{
_services.AddTransient(typeof(IDefaultRequestHandler), handlerType);
_services.Add(new ServiceDescriptor(typeof(IDefaultRequestHandler), handlerType, GetLifetime(scope)));
return this;
}

public IMediatorBuilder AddDefaultRequestHandler<THandler>() where THandler : class, IDefaultRequestHandler
public IMediatorBuilder AddDefaultRequestHandler<THandler>(RegistrationScope scope = RegistrationScope.Transient) where THandler : class, IDefaultRequestHandler
{
_services.AddTransient<IDefaultRequestHandler, THandler>();
_services.Add(new ServiceDescriptor(typeof(IDefaultRequestHandler), typeof(THandler), GetLifetime(scope)));
return this;
}

public IMediatorBuilder AddDefaultNotificationHandler(Type handlerType)
public IMediatorBuilder AddDefaultNotificationHandler(Type handlerType, RegistrationScope scope = RegistrationScope.Transient)
{
_services.AddTransient(typeof(IDefaultNotificationHandler), handlerType);
_services.Add(new ServiceDescriptor(typeof(IDefaultNotificationHandler), handlerType, GetLifetime(scope)));
return this;
}

public IMediatorBuilder AddDefaultNotificationHandler<THandler>() where THandler : class, IDefaultNotificationHandler
public IMediatorBuilder AddDefaultNotificationHandler<THandler>(RegistrationScope scope = RegistrationScope.Transient) where THandler : class, IDefaultNotificationHandler
{
_services.AddTransient<IDefaultNotificationHandler, THandler>();
_services.Add(new ServiceDescriptor(typeof(IDefaultNotificationHandler), typeof(THandler), GetLifetime(scope)));
return this;
}

public IMediatorBuilder AddDefaultStreamRequestHandler(Type handlerType)
public IMediatorBuilder AddDefaultStreamRequestHandler(Type handlerType, RegistrationScope scope = RegistrationScope.Transient)
{
_services.AddTransient(typeof(IDefaultStreamRequestHandler), handlerType);
_services.Add(new ServiceDescriptor(typeof(IDefaultStreamRequestHandler), handlerType, GetLifetime(scope)));
return this;
}

public IMediatorBuilder AddDefaultStreamRequestHandler<THandler>() where THandler : class, IDefaultStreamRequestHandler
public IMediatorBuilder AddDefaultStreamRequestHandler<THandler>(RegistrationScope scope = RegistrationScope.Transient) where THandler : class, IDefaultStreamRequestHandler
{
_services.AddTransient<IDefaultStreamRequestHandler, THandler>();
_services.Add(new ServiceDescriptor(typeof(IDefaultStreamRequestHandler), typeof(THandler), GetLifetime(scope)));
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ namespace Zapto.Mediator;

public partial class MediatorBuilder
{
public IMediatorBuilder AddNotificationHandler<TNotification, THandler>()
public IMediatorBuilder AddNotificationHandler<TNotification, THandler>(RegistrationScope scope = RegistrationScope.Transient)
where TNotification : INotification
where THandler : class, INotificationHandler<TNotification>
{
if (_ns == null)
{
_services.AddTransient<INotificationHandler<TNotification>, THandler>();
_services.Add(new ServiceDescriptor(typeof(INotificationHandler<TNotification>), typeof(THandler), GetLifetime(scope)));
}
else
{
_services.TryAddTransient<THandler>();
_services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), GetLifetime(scope)));
_services.AddSingleton<INamespaceNotificationHandler<TNotification>>(new NamespaceNotificationHandlerProvider<TNotification, THandler>(_ns.Value));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public IMediatorBuilder AddPipelineBehavior<TRequest, TResponse>(IPipelineBehavi
return this;
}

public IMediatorBuilder AddPipelineBehavior(Type behaviorType)
public IMediatorBuilder AddPipelineBehavior(Type behaviorType, RegistrationScope scope = RegistrationScope.Transient)
{
var handlers = behaviorType.GetInterfaces()
.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IPipelineBehavior<,>))
Expand All @@ -37,26 +37,27 @@ public IMediatorBuilder AddPipelineBehavior(Type behaviorType)
{ IsGenericType: true } when HasGenericParameter(responseType) => responseType.GetGenericTypeDefinition(),
_ => responseType
},
behaviorType);
behaviorType,
scope);
}

return this;
}

public IMediatorBuilder AddPipelineBehavior(Type requestType, Type? responseType, Type behaviorType)
public IMediatorBuilder AddPipelineBehavior(Type requestType, Type? responseType, Type behaviorType, RegistrationScope scope = RegistrationScope.Transient)
{
if (requestType.IsGenericType || responseType is null || responseType.IsGenericTypeDefinition)
{
throw new NotSupportedException("Generic pipeline behaviors are not supported.");
}

_services.AddTransient(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType), behaviorType);
_services.Add(new ServiceDescriptor(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType), behaviorType, GetLifetime(scope)));
return this;
}

public IMediatorBuilder AddPipelineBehavior<TRequest, TResponse, TBehavior>() where TRequest : notnull where TBehavior : class, IPipelineBehavior<TRequest, TResponse>
public IMediatorBuilder AddPipelineBehavior<TRequest, TResponse, TBehavior>(RegistrationScope scope = RegistrationScope.Transient) where TRequest : notnull where TBehavior : class, IPipelineBehavior<TRequest, TResponse>
{
_services.AddSingleton<IPipelineBehavior<TRequest, TResponse>, TBehavior>();
_services.Add(new ServiceDescriptor(typeof(IPipelineBehavior<TRequest, TResponse>), typeof(TBehavior), GetLifetime(scope)));
return this;
}

Expand All @@ -66,7 +67,7 @@ public IMediatorBuilder AddStreamPipelineBehavior<TRequest, TResponse>(IStreamPi
return this;
}

public IMediatorBuilder AddStreamPipelineBehavior(Type behaviorType)
public IMediatorBuilder AddStreamPipelineBehavior(Type behaviorType, RegistrationScope scope = RegistrationScope.Transient)
{
var handlers = behaviorType.GetInterfaces()
.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IStreamPipelineBehavior<,>))
Expand All @@ -90,26 +91,27 @@ public IMediatorBuilder AddStreamPipelineBehavior(Type behaviorType)
{ IsGenericType: true } when HasGenericParameter(responseType) => responseType.GetGenericTypeDefinition(),
_ => responseType
},
behaviorType);
behaviorType,
scope);
}

return this;
}

public IMediatorBuilder AddStreamPipelineBehavior(Type requestType, Type? responseType, Type behaviorType)
public IMediatorBuilder AddStreamPipelineBehavior(Type requestType, Type? responseType, Type behaviorType, RegistrationScope scope = RegistrationScope.Transient)
{
if (requestType.IsGenericType || responseType is null || responseType.IsGenericTypeDefinition)
{
throw new NotSupportedException("Generic pipeline behaviors are not supported.");
}

_services.AddTransient(typeof(IStreamPipelineBehavior<,>).MakeGenericType(requestType, responseType), behaviorType);
_services.Add(new ServiceDescriptor(typeof(IStreamPipelineBehavior<,>).MakeGenericType(requestType, responseType), behaviorType, GetLifetime(scope)));
return this;
}

public IMediatorBuilder AddStreamPipelineBehavior<TRequest, TResponse, TBehavior>() where TRequest : IStreamRequest<TResponse> where TBehavior : class, IStreamPipelineBehavior<TRequest, TResponse>
public IMediatorBuilder AddStreamPipelineBehavior<TRequest, TResponse, TBehavior>(RegistrationScope scope = RegistrationScope.Transient) where TRequest : IStreamRequest<TResponse> where TBehavior : class, IStreamPipelineBehavior<TRequest, TResponse>
{
_services.AddSingleton<IStreamPipelineBehavior<TRequest, TResponse>, TBehavior>();
_services.Add(new ServiceDescriptor(typeof(IStreamPipelineBehavior<TRequest, TResponse>), typeof(TBehavior), GetLifetime(scope)));
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@ namespace Zapto.Mediator;

public partial class MediatorBuilder
{
public IMediatorBuilder AddRequestHandler<TRequest, TResponse, THandler>()
public IMediatorBuilder AddRequestHandler<TRequest, TResponse, THandler>(RegistrationScope scope = RegistrationScope.Transient)
where TRequest : IRequest<TResponse>
where THandler : class, IRequestHandler<TRequest, TResponse>
{
if (_ns == null)
{
_services.AddTransient<IRequestHandler<TRequest, TResponse>, THandler>();
_services.Add(new ServiceDescriptor(typeof(IRequestHandler<TRequest, TResponse>), typeof(THandler), GetLifetime(scope)));
}
else
{
_services.TryAddTransient<THandler>();
_services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), GetLifetime(scope)));
_services.AddSingleton<INamespaceRequestHandler<TRequest, TResponse>>(new NamespaceRequestHandlerProvider<TRequest, TResponse, THandler>(_ns.Value));
}

return this;
}

public IMediatorBuilder AddRequestHandler<TRequest, THandler>()
public IMediatorBuilder AddRequestHandler<TRequest, THandler>(RegistrationScope scope = RegistrationScope.Transient)
where TRequest : IRequest<Unit>
where THandler : class, IRequestHandler<TRequest, Unit>
{
return AddRequestHandler<TRequest, Unit, THandler>();
return AddRequestHandler<TRequest, Unit, THandler>(scope);
}

public IMediatorBuilder AddRequestHandler<TRequest, TResponse>(IRequestHandler<TRequest, TResponse> handler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@ namespace Zapto.Mediator;

public partial class MediatorBuilder
{
public IMediatorBuilder AddStreamRequestHandler<TRequest, TResponse, THandler>()
public IMediatorBuilder AddStreamRequestHandler<TRequest, TResponse, THandler>(RegistrationScope scope = RegistrationScope.Transient)
where TRequest : IStreamRequest<TResponse>
where THandler : class, IStreamRequestHandler<TRequest, TResponse>
{
if (_ns == null)
{
_services.AddTransient<IStreamRequestHandler<TRequest, TResponse>, THandler>();
_services.Add(new ServiceDescriptor(typeof(IStreamRequestHandler<TRequest, TResponse>), typeof(THandler), GetLifetime(scope)));
}
else
{
_services.TryAddTransient<THandler>();
_services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), GetLifetime(scope)));
_services.AddSingleton<INamespaceStreamRequestHandler<TRequest, TResponse>>(new NamespaceStreamRequestHandlerProvider<TRequest, TResponse, THandler>(_ns.Value));
}

return this;
}

public IMediatorBuilder AddStreamRequestHandler<TRequest, THandler>()
public IMediatorBuilder AddStreamRequestHandler<TRequest, THandler>(RegistrationScope scope = RegistrationScope.Transient)
where TRequest : IStreamRequest<Unit>
where THandler : class, IStreamRequestHandler<TRequest, Unit>
{
return AddStreamRequestHandler<TRequest, Unit, THandler>();
return AddStreamRequestHandler<TRequest, Unit, THandler>(scope);
}

public IMediatorBuilder AddStreamRequestHandler<TRequest, TResponse>(IStreamRequestHandler<TRequest, TResponse> handler)
Expand Down
11 changes: 11 additions & 0 deletions src/Mediator.DependencyInjection/Builder/MediatorBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,15 @@ public IMediatorBuilder AddNamespace(MediatorNamespace ns)
{
return new MediatorBuilder(_services, ns);
}

private ServiceLifetime GetLifetime(RegistrationScope scope)
{
return scope switch
{
RegistrationScope.Transient => ServiceLifetime.Transient,
RegistrationScope.Singleton => ServiceLifetime.Singleton,
RegistrationScope.Scoped => ServiceLifetime.Scoped,
_ => throw new ArgumentOutOfRangeException(nameof(scope), scope, null)
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,23 @@ public partial class MediatorBuilder
{
public IMediatorBuilder AddNotificationHandler(
Type notificationType,
Type handlerType)
Type handlerType,
RegistrationScope scope = RegistrationScope.Transient)
{
if (notificationType.IsGenericType)
{
_services.AddTransient(handlerType);
_services.Add(new ServiceDescriptor(handlerType, handlerType, GetLifetime(scope)));
_services.AddSingleton(new GenericNotificationRegistration(notificationType, handlerType));
}
else
{
_services.AddTransient(typeof(INotificationHandler<>).MakeGenericType(notificationType), handlerType);
_services.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType), handlerType, GetLifetime(scope)));
}

return this;
}

public IMediatorBuilder AddNotificationHandler(Type handlerType)
public IMediatorBuilder AddNotificationHandler(Type handlerType, RegistrationScope scope = RegistrationScope.Transient)
{
var handlers = handlerType.GetInterfaces()
.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(INotificationHandler<>))
Expand All @@ -41,16 +42,17 @@ public IMediatorBuilder AddNotificationHandler(Type handlerType)

AddNotificationHandler(
notificationType,
handlerType);
handlerType,
scope);
}

return this;
}

public IMediatorBuilder AddNotificationHandler<THandler>()
public IMediatorBuilder AddNotificationHandler<THandler>(RegistrationScope scope = RegistrationScope.Transient)
where THandler : INotificationHandler
{
AddNotificationHandler(typeof(THandler));
AddNotificationHandler(typeof(THandler), scope);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,23 @@ public partial class MediatorBuilder
public IMediatorBuilder AddRequestHandler(
Type requestType,
Type? responseType,
Type handlerType)
Type handlerType,
RegistrationScope scope = RegistrationScope.Transient)
{
if (requestType.IsGenericType || responseType is null || responseType.IsGenericTypeDefinition)
{
_services.AddTransient(handlerType);
_services.Add(new ServiceDescriptor(handlerType, handlerType, GetLifetime(scope)));
_services.AddSingleton(new GenericRequestRegistration(requestType, responseType, handlerType));
}
else
{
_services.AddTransient(typeof(IRequestHandler<,>).MakeGenericType(requestType, responseType), handlerType);
_services.Add(new ServiceDescriptor(typeof(IRequestHandler<,>).MakeGenericType(requestType, responseType), handlerType, GetLifetime(scope)));
}

return this;
}

public IMediatorBuilder AddRequestHandler(Type handlerType)
public IMediatorBuilder AddRequestHandler(Type handlerType, RegistrationScope scope = RegistrationScope.Transient)
{
var handlers = handlerType.GetInterfaces()
.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IRequestHandler<,>))
Expand All @@ -49,7 +50,8 @@ public IMediatorBuilder AddRequestHandler(Type handlerType)
{ IsGenericType: true } when HasGenericParameter(responseType) => responseType.GetGenericTypeDefinition(),
_ => responseType
},
handlerType);
handlerType,
scope);
}

return this;
Expand All @@ -70,10 +72,10 @@ private static bool HasGenericParameter(Type type)
return false;
}

public IMediatorBuilder AddRequestHandler<THandler>()
public IMediatorBuilder AddRequestHandler<THandler>(RegistrationScope scope = RegistrationScope.Transient)
where THandler : IRequestHandler
{
AddRequestHandler(typeof(THandler));
AddRequestHandler(typeof(THandler), scope);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Zapto.Mediator;

public partial class MediatorBuilder
{
public IMediatorBuilder AddStreamRequestHandler(Type handlerType)
public IMediatorBuilder AddStreamRequestHandler(Type handlerType, RegistrationScope scope = RegistrationScope.Transient)
{
var handlers = handlerType.GetInterfaces()
.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IStreamRequestHandler<,>))
Expand All @@ -31,30 +31,32 @@ public IMediatorBuilder AddStreamRequestHandler(Type handlerType)
{ IsGenericType: true } when HasGenericParameter(responseType) => responseType.GetGenericTypeDefinition(),
_ => responseType
},
handlerType);
handlerType,
scope);
}

return this;
}

public IMediatorBuilder AddStreamRequestHandler<THandler>() where THandler : IStreamRequestHandler
public IMediatorBuilder AddStreamRequestHandler<THandler>(RegistrationScope scope = RegistrationScope.Transient) where THandler : IStreamRequestHandler
{
return AddStreamRequestHandler(typeof(THandler));
return AddStreamRequestHandler(typeof(THandler), scope);
}

public IMediatorBuilder AddStreamRequestHandler(
Type requestType,
Type? responseType,
Type handlerType)
Type handlerType,
RegistrationScope scope = RegistrationScope.Transient)
{
if (requestType.IsGenericType || responseType is null || responseType.IsGenericTypeDefinition)
{
_services.AddTransient(handlerType);
_services.Add(new ServiceDescriptor(handlerType, handlerType, GetLifetime(scope)));
_services.AddSingleton(new GenericStreamRequestRegistration(requestType, responseType, handlerType));
}
else
{
_services.AddTransient(typeof(IStreamRequestHandler<,>).MakeGenericType(requestType, responseType), handlerType);
_services.Add(new ServiceDescriptor(typeof(IStreamRequestHandler<,>).MakeGenericType(requestType, responseType), handlerType, GetLifetime(scope)));
}

return this;
Expand Down
Loading

0 comments on commit 0e94449

Please sign in to comment.