-
Notifications
You must be signed in to change notification settings - Fork 395
/
Copy pathHostedCommandHandler.cs
68 lines (64 loc) · 3.73 KB
/
HostedCommandHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System.CommandLine.Hosting;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
namespace System.CommandLine.Invocation
{
/// <summary>
/// Proviveds helper methods to initialize a command handler that uses
/// Dependency Injection from the .NET Generic Host to materialize
/// the handler.
/// </summary>
/// <seealso cref="CommandHandler"/>
public static class HostedCommandHandler
{
private class HostedCommandHandlerWrapper<THostedCommandHandler> : ICommandHandler
where THostedCommandHandler : ICommandHandler
{
public Task<int> InvokeAsync(InvocationContext context)
{
var host = context.GetHost();
var handler = host.Services.GetRequiredService<THostedCommandHandler>();
return handler.InvokeAsync(context);
}
}
/// <summary>
/// Creates an <see cref="ICommandHandler"/> instance that when invoked
/// will forward the <see cref="InvocationContext"/> to an instance of
/// <paramref name="commandHandlerType"/> obtained from the DI-container
/// of the .NET Generic Host used in the invocation pipeline.
/// </summary>
/// <param name="commandHandlerType">A command handler service type implementing <see cref="ICommandHandler"/> that has been registered with the .NET Generic Host DI-container.</param>
/// <returns>A wrapper object that implements the <see cref="ICommandHandler"/> interface by forwarding the call to <see cref="ICommandHandler.InvokeAsync(InvocationContext)"/> to the implementation of <typeparamref name="TCommandHandler"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="commandHandlerType"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="commandHandlerType"/> does not implement the <see cref="ICommandHandler"/> interface type.</exception>
public static ICommandHandler CreateFromHost(Type commandHandlerType)
{
_ = commandHandlerType ?? throw new ArgumentNullException(nameof(commandHandlerType));
Type wrapperHandlerType;
try
{
wrapperHandlerType = typeof(HostedCommandHandlerWrapper<>)
.MakeGenericType(commandHandlerType);
}
catch (ArgumentException argExcept)
{
throw new ArgumentException(
paramName: nameof(commandHandlerType),
message: $"{commandHandlerType} does not implement the {typeof(ICommandHandler)} interface.",
innerException: argExcept);
}
return (ICommandHandler)Activator.CreateInstance(wrapperHandlerType);
}
/// <summary>
/// Creates an <see cref="ICommandHandler"/> instance that when invoked
/// will forward the <see cref="InvocationContext"/> to an instance of
/// <typeparamref name="TCommandHandler"/> obtained from the DI-container
/// of the .NET Generic Host used in the invocation pipeline.
/// </summary>
/// <typeparam name="TCommandHandler">A command handler service type that has been registered with the .NET Generic Host DI-container.</typeparam>
/// <returns>A wrapper object that implements the <see cref="ICommandHandler"/> interface by forwarding the call to <see cref="ICommandHandler.InvokeAsync(InvocationContext)"/> to the implementation of <typeparamref name="TCommandHandler"/>.</returns>
public static ICommandHandler CreateFromHost<TCommandHandler>()
where TCommandHandler : ICommandHandler =>
new HostedCommandHandlerWrapper<TCommandHandler>();
}
}