Skip to content

Commit 5b1ebad

Browse files
Aymen TROUDIAymen TROUDI
authored andcommitted
First commit !
1 parent 21a64e1 commit 5b1ebad

25 files changed

+830
-0
lines changed

01-Way/01-Way.csproj

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<RootNamespace>_01_Way</RootNamespace>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
13+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
14+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
15+
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
16+
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
17+
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.21308.1" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<None Update="appsettings.json">
22+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
23+
</None>
24+
</ItemGroup>
25+
26+
</Project>

01-Way/Program.cs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
using System.CommandLine;
2+
using System.CommandLine.Builder;
3+
using System.CommandLine.Invocation;
4+
using System.CommandLine.Parsing;
5+
using System.Reflection;
6+
using Microsoft.Extensions.Configuration;
7+
using Microsoft.Extensions.DependencyInjection;
8+
using Microsoft.Extensions.Hosting;
9+
using Microsoft.Extensions.Logging;
10+
using Microsoft.Extensions.Logging.Console;
11+
12+
namespace _01_Way;
13+
14+
public static class Program
15+
{
16+
public static async Task Main(string[] args)
17+
{
18+
using var host = CreateHostBuilder(args).Build();
19+
20+
var rootCommand = new RootCommand
21+
{
22+
BuildUpperSubCommand(),
23+
BuildLowerSubCommand()
24+
};
25+
26+
var commandLine = new CommandLineBuilder(rootCommand)
27+
.UseDefaults()
28+
.Build();
29+
30+
await commandLine.InvokeAsync(args);
31+
}
32+
33+
private static Command BuildUpperSubCommand()
34+
{
35+
var command = new Command("upper")
36+
{
37+
Handler = CommandHandler.Create<string>(input => Console.WriteLine(input.ToUpper()))
38+
};
39+
40+
command.AddArgument(new Argument<string>("input"));
41+
42+
return command;
43+
}
44+
45+
private static Command BuildLowerSubCommand()
46+
{
47+
var command = new Command("lower")
48+
{
49+
Handler = CommandHandler.Create<string>(input => Console.WriteLine(input.ToLower()))
50+
};
51+
52+
command.AddArgument(new Argument<string>("input"));
53+
54+
return command;
55+
}
56+
57+
private static IHostBuilder CreateHostBuilder(string[] args) =>
58+
Host.CreateDefaultBuilder(args)
59+
.ConfigureAppConfiguration((_, config) =>
60+
{
61+
config.AddCommandLine(args);
62+
config.AddEnvironmentVariables();
63+
config.SetBasePath(GetDirectoryPath());
64+
var environment = Environment.GetEnvironmentVariable("ENVIRONMENT");
65+
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
66+
config.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true);
67+
})
68+
.ConfigureLogging((hostingContext, loggingBuilder) =>
69+
{
70+
loggingBuilder.AddConsoleLogger();
71+
loggingBuilder.AddNonGenericLogger();
72+
loggingBuilder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
73+
});
74+
75+
private static void AddConsoleLogger(this ILoggingBuilder loggingBuilder)
76+
{
77+
if (!File.Exists(GetSettingFilePath()))
78+
{
79+
loggingBuilder.AddSimpleConsole(options =>
80+
{
81+
options.SingleLine = true;
82+
options.IncludeScopes = true;
83+
options.UseUtcTimestamp = true;
84+
options.TimestampFormat = "[HH:mm:ss:fff] ";
85+
options.ColorBehavior = LoggerColorBehavior.Enabled;
86+
});
87+
}
88+
}
89+
90+
private static void AddNonGenericLogger(this ILoggingBuilder loggingBuilder)
91+
{
92+
var categoryName = typeof(Program).Namespace ?? string.Empty;
93+
var services = loggingBuilder.Services;
94+
services.AddSingleton(serviceProvider =>
95+
{
96+
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
97+
return loggerFactory.CreateLogger(categoryName);
98+
});
99+
}
100+
101+
private static string GetSettingFilePath() => Path.GetFullPath(Path.Combine(GetDirectoryPath(), @"appsettings.json"));
102+
103+
private static string GetDirectoryPath()
104+
{
105+
try
106+
{
107+
return Path.GetDirectoryName(GetAssemblyLocation()) ?? "./";
108+
}
109+
catch
110+
{
111+
return Directory.GetCurrentDirectory();
112+
}
113+
}
114+
115+
private static string GetAssemblyLocation() => Assembly.GetExecutingAssembly().Location;
116+
}

01-Way/appsettings.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Trace",
5+
"Microsoft": "Warning"
6+
},
7+
"Console": {
8+
"LogLevel": {
9+
"Default": "Information"
10+
},
11+
"FormatterName": "simple",
12+
"FormatterOptions": {
13+
"SingleLine": true,
14+
"IncludeScopes": true,
15+
"UseUtcTimestamp": true,
16+
"TimestampFormat": "[HH:mm:ss:fff] "
17+
}
18+
}
19+
}
20+
}

02-Way/02-Way.csproj

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<RootNamespace>_02_Way</RootNamespace>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
13+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
14+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
15+
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
16+
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
17+
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.21308.1" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<None Update="appsettings.json">
22+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
23+
</None>
24+
</ItemGroup>
25+
26+
</Project>

02-Way/FluentArgumentBuilder.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.CommandLine;
2+
3+
namespace _02_Way;
4+
5+
public class FluentArgumentBuilder<T> : IFluentArgumentBuilder<T>
6+
{
7+
private string? _name;
8+
private string? _description;
9+
private Func<T>? _getDefaultValue;
10+
11+
public IFluentArgumentBuilder<T> WithName(string name)
12+
{
13+
_name = name ?? throw new ArgumentNullException(nameof(name));
14+
return this;
15+
}
16+
17+
public IFluentArgumentBuilder<T> WithDescription(string description)
18+
{
19+
_description = description ?? throw new ArgumentNullException(nameof(description));
20+
return this;
21+
}
22+
23+
public IFluentArgumentBuilder<T> WithDefaultValue(Func<T> getDefaultValue)
24+
{
25+
_getDefaultValue = getDefaultValue ?? throw new ArgumentNullException(nameof(getDefaultValue));
26+
return this;
27+
}
28+
29+
public Argument<T> Build()
30+
{
31+
return _getDefaultValue is null
32+
? new Argument<T>(_name!, _description)
33+
: new Argument<T>(_name!, _getDefaultValue, _description);
34+
}
35+
}

02-Way/FluentCommandBuilder.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System.CommandLine;
2+
using System.CommandLine.Invocation;
3+
using System.Reflection;
4+
5+
namespace _02_Way;
6+
7+
public class FluentCommandBuilder : IFluentCommandBuilder
8+
{
9+
private string? _name;
10+
private string? _description;
11+
private ICommandHandler? _commandHandler;
12+
private readonly List<Argument> _arguments = new();
13+
14+
public IFluentCommandBuilder WithName(string name)
15+
{
16+
_name = name ?? throw new ArgumentNullException(nameof(name));
17+
return this;
18+
}
19+
20+
public IFluentCommandBuilder WithDescription(string description)
21+
{
22+
_description = description ?? throw new ArgumentNullException(nameof(description));
23+
return this;
24+
}
25+
26+
public IFluentCommandBuilder WithArgument<T>(Action<IFluentArgumentBuilder<T>> configureArguments)
27+
{
28+
var argumentBuilder = new FluentArgumentBuilder<T>();
29+
configureArguments(argumentBuilder);
30+
var argument = argumentBuilder.Build();
31+
_arguments.Add(argument);
32+
return this;
33+
}
34+
35+
public IFluentCommandBuilder WithHandler(string methodName)
36+
{
37+
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Static;
38+
var method = typeof(Program).GetMethod(methodName, flags);
39+
return WithHandler(CommandHandler.Create(method!));
40+
}
41+
42+
public IFluentCommandBuilder WithHandler<T>(Action<T> action)
43+
{
44+
return WithHandler(CommandHandler.Create(action));
45+
}
46+
47+
public IFluentCommandBuilder WithHandler(ICommandHandler commandHandler)
48+
{
49+
_commandHandler = commandHandler ?? throw new ArgumentNullException(nameof(commandHandler));
50+
return this;
51+
}
52+
53+
public IFluentCommand Build()
54+
{
55+
var command = new FluentCommand(_name!, _description)
56+
{
57+
Handler = _commandHandler
58+
};
59+
60+
command.AddArguments(_arguments);
61+
62+
return command;
63+
}
64+
}

02-Way/FluentCommandLine.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.CommandLine;
2+
using System.CommandLine.Builder;
3+
using System.CommandLine.Parsing;
4+
5+
namespace _02_Way;
6+
7+
public class FluentCommandLine : IFluentCommandLine
8+
{
9+
private readonly RootCommand _rootCommand;
10+
11+
public FluentCommandLine(RootCommand rootCommand)
12+
{
13+
_rootCommand = rootCommand ?? throw new ArgumentNullException(nameof(rootCommand));
14+
}
15+
16+
public Task<int> RunAsync(string[] args)
17+
{
18+
var commandLine = new CommandLineBuilder(_rootCommand)
19+
.UseDefaults()
20+
.Build();
21+
22+
return commandLine.InvokeAsync(args);
23+
}
24+
}

02-Way/FluentCommandLineBuilder.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.CommandLine;
2+
3+
namespace _02_Way;
4+
5+
public class FluentCommandLineBuilder : IFluentCommandLineBuilder
6+
{
7+
private readonly List<IFluentCommand> _subCommands = new();
8+
9+
public IFluentCommandLineBuilder AddCommand(Action<IFluentCommandBuilder> configureCommand)
10+
{
11+
var commandBuilder = new FluentCommandBuilder();
12+
configureCommand(commandBuilder);
13+
var command = commandBuilder.Build();
14+
_subCommands.Add(command);
15+
return this;
16+
}
17+
18+
public IFluentCommandLine Build()
19+
{
20+
var rootCommand = new RootCommand();
21+
22+
var subCommands = _subCommands.Cast<FluentCommand>();
23+
24+
foreach (var subCommand in subCommands)
25+
{
26+
rootCommand.AddCommand(subCommand);
27+
}
28+
29+
return new FluentCommandLine(rootCommand);
30+
}
31+
}

02-Way/IFluentArgumentBuilder.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.CommandLine;
2+
3+
namespace _02_Way;
4+
5+
public interface IFluentArgumentBuilder<T>
6+
{
7+
IFluentArgumentBuilder<T> WithName(string name);
8+
IFluentArgumentBuilder<T> WithDescription(string description);
9+
IFluentArgumentBuilder<T> WithDefaultValue(Func<T> getDefaultValue);
10+
Argument<T> Build();
11+
}

02-Way/IFluentCommand.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.CommandLine;
2+
3+
namespace _02_Way;
4+
5+
public interface IFluentCommand : ICommand
6+
{
7+
}
8+
9+
public class FluentCommand : Command, IFluentCommand
10+
{
11+
public FluentCommand(string name, string? description = null) : base(name, description)
12+
{
13+
}
14+
15+
public void AddArguments(IEnumerable<Argument> arguments)
16+
{
17+
foreach (var argument in arguments)
18+
{
19+
AddArgument(argument);
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)