What I have learned by building .NET Stars -part 5 – always available data for a display website

What I have learned by building .NET Stars -part 5 – always available data for a display website

Dotnet Stars being a site just for displaying data, it does not require an API per se. Yes, for development purposes it needs a database and an API to display – but later – the data could be retrieved from local.

The first part is to write data in JSON files near to Blazor . But how to export by default this ?

And here ASPIRE thrives : I have made a console app to export data – and registered in ASPIRE with dependency of Blazor – and can see where Blazor folder is.

this is the extension

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public static IResourceBuilder<TRes> AddPathToEnvironmment<TProject,TRes>(
        this IResourceBuilder<TRes> builder, TProject p, string name)
        where TProject : IProjectMetadata, new()
        where TRes : IResourceWithEnvironment           
{
    //var p = new TProject();       
    string pathPrj = p.ProjectPath;
    var fi = new FileInfo(pathPrj);
    string dirName = fi?.DirectoryName ?? "";
    var projectBuilder = builder
        .WithEnvironment(ctx=>
        {
            ctx.EnvironmentVariables[name] =dirName;
            ctx.EnvironmentVariables[$"{name}csproj"] = pathPrj;
        });
 
    return projectBuilder;
}

and this is how it is used

1
2
3
4
5
6
var exportToJson = builder.AddProject<Projects.StatsExport>("statsExport")
    .WithReference(ui)   
    .WithReference(db)
    .WaitFor(db)
    .AddPathToEnvironmment(new Projects.StatsBlazorUI(),"pathToWrite")
    ;

And the code that uses this

1
2
3
4
5
6
var pathToWrite = Environment.GetEnvironmentVariable("pathToWrite");
if (string.IsNullOrWhiteSpace(pathToWrite))
{
    Console.WriteLine("please add a path to write");
    return;
}

The second part is to get data from WebAPI , if available, and, if not, from JSON files.
And here the Roslyn Code Generator, https://github.com/ignatandrei/RSCG_CompositeProvider , it is useful .
We have 2 implementations of same interface ,

1
2
3
4
5
public interface IStatsData
{
   //other code
    IAsyncEnumerable<IProjectWithStars> GetProjectsWithStars();
}

And we have an implementation from WebAPI and another from JSON files

With the nugethttps://nuget.org/packages/RSCG_CompositeProviderwe can obtain data from the first that returns data.

1
2
3
4
5
6
7
8
builder.Services.AddKeyedScoped<IStatsData>("both", (sp, obj) =>
{
    var statsDataLocal = sp.GetRequiredKeyedService<IStatsData>("local_host");
    var statsDataAPI = sp.GetRequiredKeyedService<IStatsData>("statsconsole_host");
    StatsData_CP composite = new(statsDataAPI, statsDataLocal);
    composite.UseFirstTheLastOneThatWorks = true;
    return composite;
});