Category: nuget

DIForFunctions–NuGet- part3

The important part now is to make public – that means NuGet and documentation, The NuGet is pretty simple – with

dotnet pack

and with GitHub Actions – in order to do automatically every time I modify the main. For now, this is the action

name: .NET



    branches: [ “main” ]


    branches: [ “main” ]



    runs-on: ubuntu-latest


    – uses: actions/checkout@v3

    – name: Setup .NET

      uses: actions/setup-dotnet@v2


        dotnet-version: 6.0.x

    – name: Restore dependencies

      run: |

        cd src

        cd FunctionsWithDI

        dotnet tool restore

        dotnet pwsh readme.ps1

        dotnet restore

    – name: Build

      run: |

        cd src

        cd FunctionsWithDI

        dotnet build –no-restore

    – name: TestConsoleProject

run:  |

        cd src

        cd FunctionsWithDI

        cd TestConsoleApp

        dotnet run  –no-build

    – name: create package

if: ${{ github.ref == ‘refs/heads/main’ }}

run: |

        cd src

        cd FunctionsWithDI

        echo ‘now aop’

        #dotnet pwsh AOPMethod.ps1

        #dotnet clean 

        #dotnet build

        echo ‘now pack’

        dotnet pack RSCG_FunctionsWithDI/RSCG_FunctionsWithDI.csproj                        -o nugetPackages  –include-symbols –include-source

        dotnet pack RSCG_FunctionsWithDI_Base/RSCG_FunctionsWithDI_Base.csproj              -o nugetPackages  –include-symbols –include-source

    – name: ‘Upload nuget’

      if: ${{ github.ref == ‘refs/heads/main’ }}

      uses: actions/upload-artifact@v2


        name: RSCG_FunctionsWithDI_${{github.run_number}}

        path: src/FunctionsWithDI/nugetPackages

        retention-days: 1

that generates at every run the packages

You will find the sources at  and the nuget at

DI for Functions- work–part 2

Let’s begin with tests  – we need to have a class with multiple functions that have multiple [FromServices} parameter. Like

public bool TestMyFunc1([FromServices] TestDI1 t1, [FromServices] TestDI2 t2, int x, int y)
             return true;
         public bool TestMyFunc2([FromServices] TestDI1 t12,  int x, int y)
             return true;

// more others

Because there are multiple functions, I need to generate very fast  – so Incremental generators to the rescue . They are documented here :  . And a good tutorial is to be found at .

Basically, this is the code

IncrementalValuesProvider<MethodDeclarationSyntax> paramDeclarations = context.SyntaxProvider
                 predicate: static (s, _) => IsSyntaxTargetForGeneration(s),
                 transform: static (ctx, _) => GetSemanticTargetForGeneration(ctx))
             .Where(static m => m is not null)!; // filter out attributed enums that we don’t care about

            IncrementalValueProvider<(Compilation, ImmutableArray<MethodDeclarationSyntax>)> compilationAndEnums = context.CompilationProvider.Combine(paramDeclarations.Collect());


and the  idea is to find the parameters of the function that has attributes – and one of those is [FromServices] . After that , find the methods that are the parent – and then the class. After that , is simple to generate a constructor with all (distinct) the [FromServices]parameters and construct the similar method with just the non-DI parameters.

Bonus : We can verify if the parameters are null and throw exception

I could do a template for defining , but – wait to see if gain some traction to modify .

You can find the sources at and the NuGet packages ( one with generator, one with [FromServices] ) at and


DI for Functions–idea – part 1

Looking at ASP.NET Core , there is a wonderful feature that  gives you thinking :  you can put in any action for a controller FromServices argument and the framework will complete from, well, services: :

public ActionResult Test([FromServices] MyFunction

What if  you can do the same with any function from any class ?

It will be good, but … how  ?  ASP.NET Core instantiate himself the functions, but I cannot do this. 

I can generate with Roslyn a function that takes not DI arguments . For example , from

public bool TestMyFunc1([FromServices] TestDI1 t1, [FromServices] TestDI2 t2, int x, int y)

Roslyn can generate this

public bool TestMyFunc1(int  x,int  y)

And call the previous function – but HOW we can retrieve the arguments ?

As I see , there are 2 options:

1.  Generate a constructor that have as a parameter the ServiceProvider and find the services from ServiceProvider

2. Generate a constructor that have the DI arguments and assign them as fields .

Now go to work!

Services.Add => 2 NuGet

If you make a NuGet package for ASP.NET Core  and you make an extension method that calls


in order to add a Sngleton / Scoped / Transient a

IWhatever =>  Whatever

implementation , please add IWhatever in a separate Nuget .

Why ? Because not all ASP>NET Core projects are made of a single project – and , if someone needs constructor injection with IWhatever in his Business Logic , he must not be forced to add the whole dependencies for just a IWhatever interface


Example: The   –   it depends upon Microsoft.AspNetCore.Http . But I want just  IServerTiming in a business logic. I do not need also the dependency of  IApplicationBuilder .

( and yes, I have started an issue: )

[NuGet]: Transplator

This is a Nuget that it is what Razor should have been. It is a Roslyn Source Code Generator that transforms template into code.



What it does:  Takes a template and generates source code for outputting anything inside.


Somewhere in the csproj:

   <CompilerVisibleProperty Include=”DebugTransplator” />
   <CompilerVisibleItemMetadata Include=”AdditionalFiles” MetadataName=”SourceItemType” />
   <CompilerVisibleItemMetadata Include=”AdditionalFiles” MetadataName=”Name” />
   <AdditionalFiles Include=”ASM.txt” SourceItemType=”Transplate” KeepMetadata=”Name” />


Somewhere in a .cs file

var response = new ASMTemplate().Render();

And the template

partial class ASMTemplate
     StringBuilder sb = new StringBuilder();
     public void WriteText(string text)
     public void WriteValue(int text)
     public void WriteValue(int? text)
         if(text != null)
             sb.AppendLine(“” + text);
     public void WriteValue(DateTime text)
         sb.AppendLine(text.ToString(“yyyy MMMM dd HH:mm:ss”));
     public void WriteValue(string text)
     public string Render()
         return sb.ToString();

[NuGet]: HealthCheck

This is a Nuget that I use in all projects when I am making any ASP.NET Core prohect



What it does:  Implements health checks for your site and/or dependencies


public void ConfigureServices(IServiceCollection services)


[NuGet]: Polly

This is a Nuget that I use in all projects when I am making HTTP calls..



What it does:  Implements all kind of policies for retrying – see

Usage: – copied from

static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
     return HttpPolicyExtensions
         .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
         .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,


This is a Nuget that I use in almost every .NET Core project to export files in an Excel format without excel on the PC.



What it does:  Create real Excel files – not just CSV


var wb = new XSSFWorkbook();
var sheet = wb.CreateSheet(“Contractors”);
for (int i = 0; i < allContractors.Count; i++)
var contractor = allContractors[i];
IRow row = sheet.CreateRow(i);
for (int j = 0; j < contractor.Length; j++)
var cell = row.CreateCell(j);


This is a Nuget that I use in almost every .NET Core project to get the error details ( 500)



What it does:  Like Razor –  a template intepreter


var template = Template.Parse(@"
<ul id='products'>
  {{ for product in products }}
      <h2>{{ }}</h2>
           Price: {{ product.price }}
           {{ product.description | string.truncate 15 }}
  {{ end }}
var result = template.Render(new { Products = this.ProductList });


This is a Nuget that I use in almost every .NET Core project to get the error details ( 500)



What it does:  Gives detailed error when encountering a 500 HTTP Code.


                 c.IncludeExceptionDetails = (context, ex) => true;               


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.