-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommandLineModuleExtensions.cs
More file actions
130 lines (116 loc) · 4.75 KB
/
CommandLineModuleExtensions.cs
File metadata and controls
130 lines (116 loc) · 4.75 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using CliFx;
using CliFx.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Modulight.Modules.CommandLine;
using System.Reflection;
namespace Modulight.Modules.Hosting
{
/// <summary>
/// Extension methods for commandline modules.
/// </summary>
public static class CommandLineModuleExtensions
{
/// <summary>
/// Use building plugin for commandline modules.
/// </summary>
/// <param name="modules"></param>
/// <param name="configureOptions"></param>
/// <returns></returns>
public static IModuleHostBuilder UseCommandLineModules(this IModuleHostBuilder modules, Action<CommandLineModuleBuilderOptions>? configureOptions = null)
{
return modules.ConfigureBuilderServices(services =>
{
services.TryAddTransient<ICommandLineModuleManifestBuilder, DefaultCommandLineModuleManifestBuilder>();
var optionsBuilder = services.AddOptions<CommandLineModuleBuilderOptions>();
if (configureOptions is not null)
{
optionsBuilder.Configure(configureOptions);
}
}).UsePlugin<CommandLineModulePlugin>().AddModule<CommandLineCoreModule>();
}
/// <summary>
/// Get commandline module host from service provider.
/// </summary>
/// <param name="host"></param>
/// <returns></returns>
public static ICommandLineModuleCollection GetCommandLineModuleCollection(this IModuleHost host) => host.Services.GetRequiredService<ICommandLineModuleCollection>();
/// <summary>
/// Test a type is a command type.
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsCommand(this Type type) => type.IsAssignableTo(typeof(ICommand));
/// <summary>
/// Ensure a type is a command type.
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static void EnsureCommand(this Type type)
{
if (!type.IsCommand())
throw new IncompatibleTypeException(type, typeof(ICommand));
}
/// <summary>
/// Add a command type to manifest.
/// </summary>
/// <param name="builder"></param>
/// <param name="type"></param>
/// <returns></returns>
public static ICommandLineModuleManifestBuilder AddCommand(this ICommandLineModuleManifestBuilder builder, Type type)
{
type.EnsureCommand();
builder.Commands.Add(type);
return builder;
}
/// <summary>
/// Add a command type to manifest.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="builder"></param>
/// <returns></returns>
public static ICommandLineModuleManifestBuilder AddCommand<T>(this ICommandLineModuleManifestBuilder builder) where T : ICommand => builder.AddCommand(typeof(T));
/// <summary>
/// Configure the builder by default from attributes.
/// </summary>
/// <param name="builder"></param>
/// <param name="type"></param>
/// <returns></returns>
public static ICommandLineModuleManifestBuilder WithDefaultsFromModuleType(this ICommandLineModuleManifestBuilder builder, Type type)
{
if (type.IsDefined(typeof(CommandsFromAssemblyAttribute)))
{
builder.WithCommandsFromModuleAssembly(type);
}
var cmdAttrs = type.GetCustomAttributes<CommandFromAttribute>(true);
foreach (var attr in cmdAttrs)
{
builder.AddCommand(attr.Type);
}
return builder;
}
/// <summary>
/// Add commands from the assembly of module.
/// </summary>
/// <param name="builder"></param>
/// <param name="type"></param>
/// <returns></returns>
public static ICommandLineModuleManifestBuilder WithCommandsFromModuleAssembly(this ICommandLineModuleManifestBuilder builder, Type type)
{
static bool IsCommand(Type type)
{
// From CliFx source code AddCommandsFromThisAssembly()
if (type.GetInterfaces().Contains(typeof(ICommand)) && type.IsDefined(typeof(CommandAttribute)) && !type.IsAbstract)
{
return !type.IsInterface;
}
return false;
}
foreach (Type item in type.Assembly.ExportedTypes.Where(IsCommand))
{
builder.AddCommand(item);
}
return builder;
}
}
}