DB2Code – part 8–closing

From now on the only work to be done is improving step by step the generating code. For example,

1. in the REST API , the code is accessing directly the database- should be an indirection layer

2. Should generate some mock classes to return data – instead of going to database ( or maybe EF In Memory is enough?)

3. Other GUI improvements

4. Generate other project types ( e.g. .NET MAUI ,  Blazor …)

But those are just small improvements  – the whole architecture of the project works and it is running fast to have functional code.

More , it can be customized at the needs of every programmer –  if they are familiar with t4 files.

However, the fact that a programmer could make very fast an application that generates code is a sign that in 20 years + the programming is in another paradigm ( not to mention ChatGPT …)

The final result is at https://marketplace.visualstudio.com/items?itemName=ignatandrei.databasetocode

Db2Code–part 7 – Angular vs React

Once you have the REACT implementation, you will think that Angular implementation will be a breeze. Not . Some pain points and differences :

1.  Angular have the power of separating components into html code and JS/TS code. While this is a feature for the developer, it becomes hard for code generators  to generate 2 different files .So it will be one file and the component will have template instead of templateURL  React, instead , is just one file/function to generate .

2.  REACT can load dynamic function with just import  the js/ts file- since all HTML in JS/TS is basically JS . To  import dynamic in Angular is a hard  – read https://angular.io/guide/dynamic-component-loader 

3. In the same idea , the Angular components must be registered into an NgModule – or make them standalone :https://angular.io/guide/standalone-components . Anyway, this affects the DI – a hard thing to do . In REACT, just import them ( and yes, framework vs library – but I wish in Angular to be easier )

4. In REACT we have the useState – in Angular there will be Signals.  I wait – the code will be prettier .

5. REACT is more ugly – with all callbacks and memos. Angular seems prettier.

6. The DI in Angular is awesome . Just decorate what you need with @Injectable

The final result is at https://marketplace.visualstudio.com/items?itemName=ignatandrei.databasetocode

Db2Code–part 6 – implementation details

Problem 1 More dbContexts

I have think that a user can have more than 1 DBContext / database implemented. If there was just only one , it were easy to add a partial to program.cs and register the database DI

services.AddDbContext<ApplicationDBContext>

in the partial .  However, if each database is generated, how to have this  ? The answer is   https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.moduleinitializerattribute?view=net-7.0

[ModuleInitializer]
    public static void AddMe()
    {
        Generated.UtilsControllers.registerContexts.Add(new RegisterApplicationDBContext());
    }

And in the WebAPI

foreach (IRegisterContext item in UtilsControllers.registerContexts)
         {
            typesContext.Add( item.AddServices(builder.Services, builder.Configuration));
         }

Problem 2 Create database if not exists

I want to let the user to create the database if it dows not exists. But how, if I do not know the name of the database ? The idea is to obtain the DBContext from the name and inject into the DI

builder.Services.AddTransient((ctx) =>
         {
             Func<string, DbContext?> a = (string dbName) =>
             {
                 var t = typesContext.First(it => it.Name == dbName);
                
                 var req = ctx.GetRequiredService(t);
                 if (req == null) return null;
                 return req as DbContext;
             };
             return a;
         });

And then obtain from the controller action

[HttpPost(“{dbName}”)]
    public async Task<bool> EnsureCreated([FromServices] Func<string, DbContext?> fact, string dbName)
    {
        var exists = AllDB.Singleton.ExistsDB(dbName);
        if (!exists)
        {
            throw new ArgumentException(“DB does not exists ” + dbName);
        }

       var req = fact(dbName);
        if(req == null)
            throw new ArgumentException(“service does not exists ” + dbName);

       return await req.Database.EnsureCreatedAsync();
    }

Problem 3 ; Generate the correct pasca case names for typescript properties

This was something difficult. But  –  I solved by simply add this

public class LowerCaseNamingPolicy : JsonNamingPolicy
{
    public override string ConvertName(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
            return name;

        return name.ToLower();
    }
}

in order to have all with lowercase

builder.Services.AddControllers()
             .AddJsonOptions(c =>
             {
                 c.JsonSerializerOptions.PropertyNamingPolicy = new LowerCaseNamingPolicy();
             })
               .PartManager.ApplicationParts.Add(new AssemblyPart(assControllers)); ;
         ;

[ADCES]- ASP.NET Endpoints & Dapr, Microservices and Azure all-up

Details

Presentation 1: ASP.NET Core usefull endpoints
Descriere : O sa prezint citeva endpoint-uri utile pentru fiecare aplicatie ASP.NET Core – health check, swagger, date time . error si cum le puteti obtine usor.
Prezentator: Andrei Ignat , http://msprogrammer.serviciipeweb.ro/

Presentation 2 : Chit-chat about Dapr, Azure Container Instances, Microservices and Azure all-up
Descriere:
Urmarind traseul Sfantului Graal al dezvoltarii software bazate pe sablonul architectural al microserviciilor ajungem inevitabil la probabil cel mai promitator proiect din ultimul deceniu care are potentialul de a simplifica dezvoltarea si mentenanta microserviciilor in productie. In aceasta sesiune vom avea ocazia sa interactionam cu Dapr (Distributed Application Runtime), sa-i aflam beneficiile si sa-l vedem la lucru in aplicatii pregatite pentru productie.
Prezentator: Alex Mang ,

Link meetup: https://www.meetup.com/bucharest-a-d-c-e-s-meetup/events/291577904/

Db2Code–part 5 – testing

For testing I should find some databases to test to ( and do not forget that generating SELECT  from PK supports just 1 PK, not multiple).

Microsoft already show some sample database – you can download from https://github.com/microsoft/sql-server-samples/tree/master/samples/databases . However , those must exists in the moment of running tests – so I have as options:

  1. Have an Sql Server ( by docker or on PC) and run the sql every time at the beginning of every start run test
  2. Have an Sqlite database file with all data and copy it .

( SqlServer in memory will be  a good options, but it do not work with Sql insert/update….)

A specific test looks like this

static void CreateDb()
{

//the restore operation just replace the sqlite database
     DatabaseOperations.Restore(context, “Pubs”);

}

[Theory]
[InlineData(SearchCriteria.Equal, ediscountsColumns.stor_id, “8042”, 1)]
[InlineData(SearchCriteria.Different, ediscountsColumns.stor_id, “8042”, 2)]
[InlineData(SearchCriteria.Equal, ediscountsColumns.stor_id, null, 2)]
[InlineData(SearchCriteria.Different, ediscountsColumns.stor_id, null, 1)]
//[InlineData(SearchCriteria.Equal, ediscountsColumns.discount, “5”, 1)]
[InlineData(SearchCriteria.Equal, ediscountsColumns.lowqty, “100”, 1)]
public async Task SearchAdvanced(SearchCriteria sc, ediscountsColumns col, string val, int nrRecs)
{
     CreateDb();
     var data = await context.discountsSimpleSearch(sc, col, val).ToArrayAsync();
     Assert.Equal(nrRecs, data.Length);
}

One consequence will be that the tests cannot run in parallel .And  , after all, it is just a work of coding data and results. Tiresome work, however pays in the long term.

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.