The Host Service and the Activity should work together:
[!important]
The Songhay Activity depends on the configuration/input and invocation of the IConfiguration interface which is provided by the [[dotnet|.NET]] Hosted Service (and [[ASP.NET]] of course).
It follows that any feature previously developed for the Songhay Activity around configuration/input and invocation should be retired. This means:
[ ] remove all Songhay.Extensions.IActivityExtensions.ToActivity* methods ππ₯
the Songhay ActivitiesGetter class is gone ππ₯ #to-do
The built-in DI features of the [[dotnet|.NET]] Generic Host totally eliminates the . The very old design goal to load Activity assemblies from disk via reflection has fallen away. This means that command-line args can specify the name of an Activity type compiled in the assembly and the wonderfully elaborate system [[Microsoft]] built around .AddCommandLine(args) [π docs ] can load args-based key-value pairs into the conventional IConfiguration [π docs ] assigned to the command line.
This IHostedService [π GitHub ] is loaded (perhaps) like this:
This switch statement effectively replaces the ActivitiesGetter concept. The Host.CreateDefaultBuilder method [π docs ] can load up to four different IConfiguration instances. One of these is for command-line args. I am very motivated to assert that these patterns from [[Microsoft]] eliminate the need for my ProgramArgs concept which has been propagating deeply into business logic ππ³.
The code sample above is based on this little POC sketch:
using Microsoft.Extensions.Hosting;
namespace Songhay.Tests;
public class GenericHostTests
{
[Theory]
[InlineData("--service", "MyHostedService")]
public void ShouldReadArgs(params string[] args)
{
IHostBuilder builder = Host.CreateDefaultBuilder(args);
builder.ConfigureServices((hostContext, services) =>
{
string serviceName = hostContext.Configuration["service"];
switch (serviceName)
{
case "MyHostedService":
break;
default:
Assert.Fail();
break;
}
});
IHost host = builder.Build();
host.Run();
}
}
the ProgramArgs help-text and conventional-parameter extensions need to be translated over into IConfiguration extensions π‘ #to-do
[[Microsoft]] has been trying to tell me this for years:
[!important]
IConfiguration [π docs ] is the cross-platform central βhubβ for initial app input.
This means:
[ ] remove all inheritance of Songhay.Abstractions.IActivity π¨π₯
[ ] move Songhay.Abstractions.IActivity.DisplayHelp to Songhay.Abstractions.IActivityHelp.DisplayHelp πβ¨
[ ] remove ProgramArgs from all IActivity members π¨π₯
[x] translate Songhay.Extensions.ProgramArgsExtensions.ToHelpDisplayText to Songhay.Extensions.IConfigurationExtensions.ToHelpDisplayText πβ¨
[x] translate Songhay.Extensions.ProgramArgsExtensions.GetBasePathValue to `Songhay.Extensions.IConfigurationExtensions.GetBasePathValue πβ¨
[x] translate Songhay.Extensions.ProgramArgsExtensions.GetOutputPath to `Songhay.Extensions.IConfigurationExtensions.GetOutputPath πβ¨
[x] translate Songhay.Extensions.ProgramArgsExtensions.GetSettings to `Songhay.Extensions.IConfigurationExtensions.GetSettingsData πβ¨
[x] translate Songhay.Extensions.ProgramArgsExtensions.GetSettingsFilePath to `Songhay.Extensions.IConfigurationExtensions.GetSettingsFilePath πβ¨
[x] translate Songhay.Extensions.ProgramArgsExtensions.GetStringInput to `Songhay.Extensions.IConfigurationExtensions.GetStringInput πβ¨
[x] translate Songhay.Extensions.ProgramArgsExtensions.IsHelpRequest to `Songhay.Extensions.IConfigurationExtensions.IsHelpRequest πβ¨
[x] translate Songhay.Extensions.ProgramArgsExtensions.WithDefaultHelpText to Songhay.Extensions.IConfigurationExtensions.WithDefaultHelpText πβ¨
[x] translate Songhay.Extensions.ProgramArgsExtensions.WriteOutputToFile overloads to `Songhay.Extensions.IConfigurationExtensions.WriteOutputToFile overloads πβ¨
[x] copy all string constants in ProgramArgs to a static class, Songhay.Models.ProgramArgsScalars πβ¨
[ ] remove ProgramArgs ππ₯
the behavior of IConfigurationExtensions.ToKeys
Since [[dotnet|.NET 6.0]], IConfiguration exposes its underlying collection via the ConfigurationExtensions.AsEnumerable extension method [π docs ]. This late edition is probably why I have not revisited IConfiguration for a large time. But now, decades later, we have this:
β¦where IConfigurationExtensions.ToKeys would return keys β
the behavior of IConfigurationExtensions.HasArg
The main concern of IConfigurationExtensions.HasArg is to remove any -- prefix from its string input because, even though Host.CreateDefaultBuilder does this automatically (by calling the .AddCommandLine(args) [π docs ] extension method under the hood) for command line args pass to IConfiguration, the Songhay ProgramArgsScalars will need -- prefix removal.
After all the prefix drama is addressed, this method can search the output of IConfigurationExtensions.ToKeys with its modified its string input.
the behavior of IConfigurationExtensions.WithDefaultHelpText
This method would search the output of IConfigurationExtensions.ToKeys for all of the constants in ProgramArgsScalars and, when a key of name foo is found, it would add a new key, foo-help, to IConfiguration.
The Host Service and the Activity should work together:
It follows that any feature previously developed for the Songhay Activity around configuration/input and invocation should be retired. This means:
Songhay.Extensions.IActivityExtensions.ToActivity*
methods ππ₯Songhay.Extensions.IActivityExtensions.WithConfiguration
ππ₯Songhay.Hosting.DefaultHostedService
πβ¨the Songhay
ActivitiesGetter
class is gone ππ₯ #to-doThe built-in DI features of the [[dotnet|.NET]] Generic Host totally eliminates the . The very old design goal to load Activity assemblies from disk via reflection has fallen away. This means that command-line
args
can specify the name of an Activity type compiled in the assembly and the wonderfully elaborate system [[Microsoft]] built around.AddCommandLine(args)
[π docs ] can loadargs
-based key-value pairs into the conventionalIConfiguration
[π docs ] assigned to the command line.This
IHostedService
[π GitHub ] is loaded (perhaps) like this:This
switch
statement effectively replaces theActivitiesGetter
concept. TheHost.CreateDefaultBuilder
method [π docs ] can load up to four differentIConfiguration
instances. One of these is for command-lineargs
. I am very motivated to assert that these patterns from [[Microsoft]] eliminate the need for myProgramArgs
concept which has been propagating deeply into business logic ππ³.The code sample above is based on this little POC sketch:
the
ProgramArgs
help-text and conventional-parameter extensions need to be translated over intoIConfiguration
extensions π‘ #to-do[[Microsoft]] has been trying to tell me this for years:
This means:
Songhay.Abstractions.IActivity
π¨π₯Songhay.Abstractions.IActivity.DisplayHelp
toSonghay.Abstractions.IActivityHelp.DisplayHelp
πβ¨ProgramArgs
from allIActivity
members π¨π₯Songhay.Abstractions.IActivityConfigurationSupport
ππ₯Songhay.Extensions.IActivityExtensions.GetActivity
ππ₯IActivityWithTask*
interfaces toIAsyncActivity*
πSonghay.Extensions.IConfigurationExtensions.ToKeys
πβ¨Songhay.Extensions.IConfigurationExtensions.HasArg
πβ¨Songhay.Extensions.ProgramArgsExtensions.ToHelpDisplayText
toSonghay.Extensions.IConfigurationExtensions.ToHelpDisplayText
πβ¨Songhay.Extensions.ProgramArgsExtensions.GetBasePathValue
to `Songhay.Extensions.IConfigurationExtensions.GetBasePathValue πβ¨Songhay.Extensions.ProgramArgsExtensions.GetOutputPath
to `Songhay.Extensions.IConfigurationExtensions.GetOutputPath πβ¨Songhay.Extensions.ProgramArgsExtensions.GetSettings
to `Songhay.Extensions.IConfigurationExtensions.GetSettingsData πβ¨Songhay.Extensions.ProgramArgsExtensions.GetSettingsFilePath
to `Songhay.Extensions.IConfigurationExtensions.GetSettingsFilePath πβ¨Songhay.Extensions.ProgramArgsExtensions.GetStringInput
to `Songhay.Extensions.IConfigurationExtensions.GetStringInput πβ¨Songhay.Extensions.ProgramArgsExtensions.IsHelpRequest
to `Songhay.Extensions.IConfigurationExtensions.IsHelpRequest πβ¨Songhay.Extensions.ProgramArgsExtensions.WithDefaultHelpText
toSonghay.Extensions.IConfigurationExtensions.WithDefaultHelpText
πβ¨Songhay.Extensions.ProgramArgsExtensions.WriteOutputToFile
overloads to `Songhay.Extensions.IConfigurationExtensions.WriteOutputToFile overloads πβ¨ProgramArgs
to a staticclass
,Songhay.Models.ProgramArgsScalars
πβ¨ProgramArgs
ππ₯the behavior of
IConfigurationExtensions.ToKeys
Since [[dotnet|.NET 6.0]],
IConfiguration
exposes its underlying collection via theConfigurationExtensions.AsEnumerable
extension method [π docs ]. This late edition is probably why I have not revisitedIConfiguration
for a large time. But now, decades later, we have this:β¦where
IConfigurationExtensions.ToKeys
would returnkeys
βthe behavior of
IConfigurationExtensions.HasArg
The main concern of
IConfigurationExtensions.HasArg
is to remove any--
prefix from itsstring
input because, even thoughHost.CreateDefaultBuilder
does this automatically (by calling the.AddCommandLine(args)
[π docs ] extension method under the hood) for command lineargs
pass toIConfiguration
, the SonghayProgramArgsScalars
will need--
prefix removal.After all the prefix drama is addressed, this method can search the output of
IConfigurationExtensions.ToKeys
with its modified itsstring
input.the behavior of
IConfigurationExtensions.WithDefaultHelpText
This method would search the output of
IConfigurationExtensions.ToKeys
for all of the constants inProgramArgsScalars
and, when a key of namefoo
is found, it would add a new key,foo-help
, toIConfiguration
.