First thing – – usage must be simple . So this is something that can be reproduces easy on each ASPIRE project :
builder.AddDotnetGlobalTools(“dotnet-ef”, “dotnet-depends”);
I cannot imagine simpler than this – and , of course, you can add many more other dotnet tools – see https://www.nuget.org/packages?q=&includeComputedFrameworks=true&packagetype=dotnettool&prerel=true&sortby=relevance
What happens:
Now a Aspire resource will be created with a command to install the specified global tools. Also, a All command will be created to install all specified global tools – or you can click to install one by one
Now , how this is executed : I have created a new class, derived from ExecutableResource , that executes
dotnet tool list -g
in order to see the global tools.
public class DotnetGlobalToolResource: ExecutableResource
{
public DotnetGlobalToolResource(): base("DotnetGlobalTool","dotnet","")
{
}
}
public static IResourceBuilder<DotnetGlobalToolResource> AddDotnetGlobalTools(
this IDistributedApplicationBuilder builder,
params string[] arr
)
{
ArgumentNullException.ThrowIfNull(builder);
var resource = new DotnetGlobalToolResource();
var res = builder.AddResource(resource).WithArgs(new string[]
{
"tool",
"list",
"-g"
})
.ExcludeFromManifest()
;
if ((arr?.Length ?? 0) == 0)
return res;
//more code, see below arr
Also, for each tool enumerated in
builder.AddDotnetGlobalTools(“dotnet-ef”, “dotnet-depends”);
I have created a command to execute.
foreach (var toolName in arr)
{
res.WithCommand(toolName, toolName,async (ExecuteCommandContext ecc)=>
{
var loggerService = ecc.ServiceProvider.GetService(typeof(ResourceLoggerService)) as ResourceLoggerService;
var logger = loggerService?.GetLogger(resource);
if (logger == null)
{
Console.WriteLine($"Logger not found for {resource.Name}");
return new ExecuteCommandResult() { Success = false, ErrorMessage = "Logger not found" };
}
return await FromTool(toolName, logger);
});
}
Finally, I have created an ALL command to install all at once
res.WithCommand("All", "!All!", async ecc =>
{
var loggerService = ecc.ServiceProvider.GetService(typeof(ResourceLoggerService)) as ResourceLoggerService;
var logger = loggerService?.GetLogger(resource);
if (logger == null)
{
Console.WriteLine($"Logger not found for {resource.Name}");
return new ExecuteCommandResult() { Success = false, ErrorMessage = "Logger not found" };
}
var commandService = ecc.ServiceProvider.GetService(typeof(ResourceCommandService)) as ResourceCommandService;
if (commandService == null)
{
Console.WriteLine($"command service not found for {resource.Name}");
return new ExecuteCommandResult() { Success = false, ErrorMessage = "Logger not found" };
}
logger.LogInformation("Starting full install...");
var nrSuccess = 0;
foreach (var toolName in arr)
{
var resTool = await commandService.ExecuteCommandAsync(resource, toolName);
if (resTool.Success)
{
nrSuccess++;
logger.LogInformation($"Installing {toolName} succeeded.");
}
else
{
logger.LogError($"Installing {toolName} failed: {resTool.ErrorMessage}");
}
}
if (nrSuccess == arr.Length)
{
logger.LogInformation("All tools installed successfully.");
return new ExecuteCommandResult() { Success = true };
}
else
{
//logger.LogWarning($"Only {nrSuccess} out of {arr.Length} tools were installed successfully.");
return new ExecuteCommandResult() { Success = false, ErrorMessage = $"Only {nrSuccess} out of {arr.Length} tools were installed successfully." };
}
});
You find the nuget package at https://www.nuget.org/packages/DotnetGlobalToolsExtensionAspire – and the source code at https://github.com/ignatandrei/aspireExtensions
Enjoy !
