Category: .NET

What I have learned by building .NET Stars -part 2- interfaces

In my latest project, building a robust system using interfaces has been both a fascinating challenge and an enlightening experience. As I embarked on this journey, it quickly became evident how immensely powerful and transformative thinking in terms of interfaces can be.

From the outset, interfacing brought clarity to several core aspects of the application:

  • Data Management: Interfaces provided a transparent view of data structures and their usage within the app.
  • Data Flow: They illuminated how data was accessed and exchanged, simplifying what seemed complex at first glance.
  • Application Flow: Interfaces helped chart out the application’s workflow, providing insights even in its dormant state.

While initially daunting, embracing interfaces has offered immense benefits almost immediately. A notable revelation was how adopting the NullObjectPattern through an interface (you can explore this further at rscg_Interface_to_null_object) enabled me to navigate and visualize my application’s flow effortlessly – a crucial step even when it performs no operations.

One of the quicker wins was leveraging interfaces to support multiple data sources. This flexibility meant that I could seamlessly pull project details from diverse platforms like the .NET Foundation, GitHub repositories such as quozd/awesome-dotnet and thangchung/awesome-dotnet-core by implementing a common interface, IStatsData, and then efficiently saving this consolidated data with a single implementation of IProjectsData.

Our interface designs have opened up a world of possibilities for flexibility and reusability. Consider these interfaces :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
[ToNullObject]
public interface IStatsData
{
    //other code
IAsyncEnumerable<IProject> RefreshProjects();
}
 
[ToNullObject]
public interface IProjectsData
{
    IAsyncEnumerable<IProject> GetProjectsAsync();
    Task<bool> SaveProjects(IProject[] projects);
 
}

 

With these interfaces, we have the freedom to implement various strategies for acquiring projects from diverse sources such as DotNetFoundation, awesome-dotnet, and awesome-dotnet-core. Moreover, we can centralize the project storage logic with just one implementation of IProjectsData.

The result is a dynamic, versatile application that not only offers rich functionality but also encourages continuous improvement.

Eager to see the fruits of this approach? You can dive into our project live at https://ignatandrei.github.io/dotnetstats/. Additionally, the source code is available for all to explore at http://github.com/ignatandrei/dotnetstats/.

Dotnet Stars–part 1

The .NET Stats project wants to show the stars for .NET github projects.

The projects are taken from .NET Foundation , https://dotnetfoundation.org/ ,
Vitali Fokin https://github.com/quozd/awesome-dotnet/
and Thang Chung https://github.com/thangchung/awesome-dotnet-core
There are more than 1000 repositories investigated.

Here are the first 30 projects with most  stars :

“ASP.NET Core” https://github.com/aspnet/home number stars 35690
“ASP.NET MVC” https://github.com/dotnet/aspnetcore number stars 35674
“Another Redis Desktop Manager” https://github.com/qishibo/AnotherRedisDesktopManager number stars 31157
“Avalonia” https://github.com/AvaloniaUI/Avalonia number stars 26327
“.NET MAUI” https://github.com/dotnet/maui number stars 22303
“Awesome .NET Core” https://github.com/thangchung/awesome-dotnet-core number stars 20073
“ASP.NET Core Developer Roadmap” https://github.com/MoienTajik/AspNetCore-Developer-Roadmap number stars 18741
“React Native for Windows” https://github.com/microsoft/react-native-windows number stars 16513
“bitwarden-core” https://github.com/bitwarden/core number stars 15891
“Entity Framework” https://github.com/dotnet/efcore number stars 13839
“Polly” https://github.com/App-vNext/Polly number stars 13504
“awesome-static-analysis” https://github.com/mre/awesome-static-analysis number stars 13452
“ABP” https://github.com/abpframework/abp number stars 13065
“AspNet Boilerplate” https://github.com/aspnetboilerplate/aspnetboilerplate number stars 11838
“awesome-ddd” https://github.com/heynickc/awesome-ddd number stars 11360
“Mono” https://github.com/mono/mono number stars 11170
“BenchmarkDotNet” https://github.com/dotnet/BenchmarkDotNet number stars 10682
“AngleSharp” https://github.com/AngleSharp/AngleSharp/issues number stars 10389
“Orleans” https://github.com/dotnet/orleans number stars 10172
“AutoMapper” https://github.com/automapper/automapper number stars 9966
“RestSharp” https://github.com/restsharp/RestSharp number stars 9646
“MahApps.Metro” https://github.com/MahApps/MahApps.Metro number stars 9355
“FluentValidation” https://github.com/fluentvalidation/fluentvalidation number stars 9160
“ML.NET” https://github.com/dotnet/machinelearning number stars 9073
“Awesome Blazor” https://github.com/AdrienTorris/awesome-blazor number stars 8895
“Humanizer” https://github.com/Humanizr/Humanizer number stars 8722
“Orchard Core” https://github.com/OrchardCMS/OrchardCore number stars 7488
“Reactive Extensions for .NET – ReactiveX” https://github.com/dotnet/reactive number stars 6765
“Stride” https://github.com/stride3d/stride number stars 6708
“Awesome Unity” https://github.com/RyanNielson/awesome-unity number stars 6702
And the first 30 projects with most  stars in 2024

“Avalonia” https://github.com/AvaloniaUI/Avalonia number stars 4477
“Another Redis Desktop Manager” https://github.com/qishibo/AnotherRedisDesktopManager number stars 3663
“ASP.NET Core” https://github.com/aspnet/home number stars 2909
“ASP.NET MVC” https://github.com/dotnet/aspnetcore number stars 2902
“.NET MAUI” https://github.com/dotnet/maui number stars 2542
“bitwarden-core” https://github.com/bitwarden/core number stars 2465
“ASP.NET Core Developer Roadmap” https://github.com/MoienTajik/AspNetCore-Developer-Roadmap number stars 2090
“Awesome .NET Core” https://github.com/thangchung/awesome-dotnet-core number stars 1551
“ABP” https://github.com/abpframework/abp number stars 1463
“Elsa Workflows” https://github.com/elsa-workflows/elsa-core number stars 1408
“Bootstrap Blazor” https://github.com/dotnetcore/BootstrapBlazor/issues number stars 1283
“awesome-static-analysis” https://github.com/mre/awesome-static-analysis number stars 1120
“BenchmarkDotNet” https://github.com/dotnet/BenchmarkDotNet number stars 1073
“Polly” https://github.com/App-vNext/Polly number stars 1001
“Entity Framework” https://github.com/dotnet/efcore number stars 994
“React Native for Windows” https://github.com/microsoft/react-native-windows number stars 979
“awesome-ddd” https://github.com/heynickc/awesome-ddd number stars 972
“Stride” https://github.com/stride3d/stride number stars 945
“Silk.NET” https://github.com/dotnet/Silk.NET number stars 929
“Verify” https://github.com/VerifyTests/Verify number stars 798
“Awesome Blazor” https://github.com/AdrienTorris/awesome-blazor number stars 775
“AngleSharp” https://github.com/AngleSharp/AngleSharp/issues number stars 762
“Python.NET” https://github.com/pythonnet/pythonnet number stars 758
“FluentValidation” https://github.com/fluentvalidation/fluentvalidation number stars 686
“.NET Community Toolkit” https://github.com/CommunityToolkit/dotnet/issues number stars 680
“Humanizer” https://github.com/Humanizr/Humanizer number stars 679
“MiniExcel” https://github.com/shps951023/MiniExcel number stars 677
“Orchard Core” https://github.com/OrchardCMS/OrchardCore number stars 660
“Orleans” https://github.com/dotnet/orleans number stars 643
“Ant Design Blazor” https://github.com/ant-design-blazor/ant-design-blazor number stars 622

You can see at https://ignatandrei.github.io/dotnetstats/ and the source code at http://github.com/ignatandrei/dotnetstats/


And now, I will let AI to transform the text with this instruction

Given the text in FILE, write a blog post that makes the paper sound exciting and encourages readers to look at it. 

Keep the links.
Do NOT use markdown , but just html tags.

Model Name ollama:llama3.2

The Unparalleled Power of .NET: A Statistics-Driven Journey

Are you fascinated by the world of programming languages and their respective communities? Do you ever wonder which projects are among the most popular and in-demand? Look no further! We’re thrilled to introduce you to the .NET Stats project, a game-changing analysis tool that sheds light on the stars of the .NET GitHub realm.

A Project With A Purpose

The team behind .NET Stats has embarked on an ambitious mission to investigate over 1,000 repositories from the .NET Foundation, Vitali Fokin’s Awesome .NET, and Thang Chung’s Awesome .NET Core. Their objective? To reveal the most starred projects in both 2023 and 2024.

Revealing The Stars

The results are nothing short of astonishing! In the first iteration, our analysis revealed some of the highest-rated .NET repositories, including ASP.NET Core with over 35,700 stars. But what’s remarkable is that these statistics are not just a snapshot ΓÇô they’re a dynamic reflection of the ever-evolving landscape of programming languages.

Fast forward to 2024, and we’re treated to an updated view of the most starred projects, with Avalonia leading the charge at an impressive 4,477 stars. As you delve deeper into our analysis, you’ll uncover new insights and perspectives that shed light on the current trends and demands in the .NET GitHub world.

A Window Into The Future

The .NET Stats project is more than just a collection of statistics; it’s an illuminating lens through which to envision the future of programming languages. By examining the projects with the most stars, we can identify areas where innovation and expertise are converging, providing an irreplaceable roadmap for aspiring developers.

Want to stay ahead of the curve? Head over to our website, https://ignatandrei.github.io/dotnetstats/, to explore the full report in-depth. You’ll find links to not only each repository mentioned but also a treasure trove of GitHub repositories across various programming languages and categories for you to discover.

Visit http://github.com/ignatandrei/dotnetstats/ to see some projects and maybe even learn something new today!

Model Name ollama:deepseek-r1

Counting Stars: The Reflection of GitHub Against .NET Ecosystem

Have you ever wondered which .NET projects hold the most stars on GitHub? Well, now you can speculate no more!

Our analysis reveals the popularity trends of .NET repositories based on GitHub’s star count. And it’s much more exciting than you might imagine.

What We Did:

We collected repository statistics from public GitHub data for over 1,000 .NET-related repositories. Our criteria? Stars count on GitHub plus additional factors like forks, issues, and releases. It was a meticulous process to ensure accurate analysis.

What We Found:

  • “.NET Core” holds the title spot this year, with an impressive 146 stars as of our last update.
  • Looking at historical data, .NET Core not only maintains its position but also leads by a significant margin compared to other popular frameworks like “Vitali Fokin” and “Thang Chung”.
Can you guess next year’s stats? Want to see what ‘2025’ brings? Click the button below:

( predicting here )

Why This Matters:

Understanding which .NET projects are popular can guide developers when choosing frameworks and tools. It’s critical to support these projects by contributing, testing, and using them.

Visit our full analysis at for a comprehensive look into the numbers and trends.

Model Name ollama:phi4

Explore the Rising Stars of .NET Projects on GitHub

Welcome tech enthusiasts! In an effort to highlight the most impressive and star-studded .NET projects, we’re excited to introduce you to the .NET Stats project. Our initiative spotlights over 1000 repositories from the vibrant .NET community.

With insights drawn from the .NET Foundation, resources by developers like Vitali Fokin (github) and Thang Chung (github), we’ve curated a comprehensive list that captures the cr├¿me de la cr├¿me of .NET projects based on GitHub stars.

This blog post takes you through the journey from popular standouts in the past to the shining lights for 2024. Dive into this rich universe, where innovation meets community collaboration at its best!

Top .NET Projects Shining Brightly

  • ASP.NET Core: Leading the charts with a staggering 35,690 stars (GitHub).
  • .NET MAUI: A front runner in cross-platform app development with 22,303 stars (GitHub).
  • Polly: Providing resilience and transient-fault-handling capabilities for .NET developers, attracting 13,504 stars (GitHub).

This is just the tip of the iceberg. Browse through a selection of renowned repositories such as Avalonia, Entity Framework Core, and many more, each one representing the pinnacle of development creativity.

The Future is Bright: .NET Projects Poised for 2024 Stardom

Looking ahead to 2024, discover which projects are poised to take center stage. Witness rising stars like Avalonia, with an impressive increase in GitHub stars to 4,477 (GitHub), and explore the continuous contributions and innovations shaping the future of .NET development.

Discover More at .NET Stats

You can delve deeper into this project and its findings through our interactive site: .NET Stats Viewer. We invite you to explore the evolving landscape of .NET projects, their growth, and their impact.

Moreover, if you’re intrigued and inspired by what you see, we encourage you to take a look at our project’s source code on GitHub, where transparency meets community participation.

Join the Conversation & Celebrate Progress!

We cordially invite you to engage with the .NET community, share your thoughts, and be part of a movement that encourages innovation and growth. Whether youΓÇÖre a developer or simply fascinated by technology’s progress, thereΓÇÖs something here for everyone at .NET Stats.

Stay tuned for more updates as we continue to track and celebrate the accomplishments of .NET projects around the world!

Model Name ollama:gemma2:27b

Want to Know Which .NET Projects Are Hottest Right Now?

Curious which .NET projects are leading the pack in 2024? The .NET Stats project has you covered!

This awesome initiative dives into over 1,000 repositories from sources like the .NET Foundation,
Vitali Fokin’s “awesome-dotnet,” and Thang Chung’s “awesome-dotnet-core” to uncover the most starred projects.

The Top Contenders

Based on historical data, here are some of the front-runners:

  • “Avalonia”: A popular cross-platform UI framework

And these heavy hitters from 2023 still hold their own:

  • “ASP.NET Core”: The ubiquitous web framework
  • “Another Redis Desktop Manager”: A powerful tool for managing your Redis databases
  • “.NET MAUI”: Build modern cross-platform apps with ease

Ready to Explore More?

Head over to https://ignatandrei.github.io/dotnetstats/ to see the full rankings, dive into project details, and discover your next favorite .NET tool! You can even check out the source code at http://github.com/ignatandrei/dotnetstats.

Don’t miss out on this great resource for staying up-to-date on the exciting world of .NET development!

Model Name ollama:smallthinker

Discover the Best .NET GitHub Projects

Welcome to the .NET Stats project, where we shine a spotlight on the most popular and well-known .NET GitHub projects. Every week, our team dives into the vibrant world of .NET development to uncover the hidden gems that deserve more recognition.

What You’ll Find Here

This blog post is your guided tour through the top-performing .NET repositories on GitHub. Each section is packed with action, including:

  • Notable Contributors: Learn about the contributors who make these projects shine.
  • Sources: Discover where your favorite GitHub projects come from.
  • Promising Projects: Explore the latest trends and categories we’ve uncovered.

Our Top 30 Picks

In this week’s edition, we’re focusing on the first 30 projects with the most stars. This massive list is a testament to the power of .NET technology in driving innovation and collaboration.

    {% for project in top_projects %}

  • {{ project.name }} ({{ project.stars }} stars)
  • {% endfor %}

Coming Soon: 2024 Projects

Don’t miss out on our weekly updates, as we’ll be featuring the top-performing projects from 2023 and providing a sneak peek into what’s to come in 2024. Stay tuned for exclusive insights!

Come Back Soon

Each week, our team delves deeper into the world of .NET development, uncovering new insights and discoveries. Join us as we continue to explore the vast expanse of GitHub projects and celebrate their successes.


Visit our blog for more!
View the source code on GitHub

Model Name ollama:falcon3:10b

Unveiling the .NET Star Power


Dive into the .NET Stats project to explore the most popular .NET Github projects. This collection is a testament to community engagement and innovation in the world of .NET development.

A Treasure Trove of .NET Projects


The .NET Stats project brings together stars from various pivotal repositories provided by entities such as:



  • .NET Foundation, showcasing projects like ASP.NET Core and .NET MAUI.

  • thangchung, with their insights into Awesome .NET Core.


These projects not only represent the cutting-edge of .NET development but also offer valuable resources for developers looking to enhance their skills or explore new technologies.

The Top .NET Projects


Check out the latest .NET stars in our comprehensive list:



For a complete rundown, visit our online hub.

Engage with the Community


Join us in celebrating the vibrant .NET developer community. Our project is more than just data; it’s a gateway to understanding which projects are making waves and why. Explore and be part of shaping the future of .NET development.

Learn more or get involved in our project.

Model Name ollama:dolphin3

The Ultimate Guide to .NET Github Projects – Unveiling the Stars

The .NET Stats project is on a quest to shine a light on spectacular Github repositories related to .NET, and we want you to join us for this exhilarating journey.

Our mission kicked off with key contributors from The .NET Foundation, as well as visionary developers such as Vitali Fokin and Thang Chung. Together, we have scoured through a vast horizon of more than 1000 repositories, unveiling some amazing .NET Github gems.

Here’s an exclusive sneak peek at the top 30 projects with the most stars:

– “ASP.NET Core” [35690 stars]
– “ASP.NET MVC” [35674 stars]
– “Another Redis Desktop Manager” [31157 stars]
– “Avalonia” [26327 stars]

…and the list goes on. Get ready to witness true .NET mastery!

If you’re eager enough to see what these remarkable projects look like in 2024, buckle up as we unveil the first 30 with the most stars:

– “Avalonia” [4477 stars]
– “Another Redis Desktop Manager” [3663 stars]

The complete roster is just a click away at our interactive online platform – Unveil the Stars. Each entry showcases its own unique contribution to the .NET universe, and provides an enticing glimpse into what awaits.

For those who want to dive deeper and unravel the intricate details of this fascinating project, we invite you to inspect our open-source GitHub repository: Dotnet Stats Github. Feel free to contribute, discuss and even participate in shaping the future of .NET development!

Are you ready to embark on an unforgettable quest through the world of talented .NET developers and uncover a universe of innovative programming projects? Join us today!

RSCG – NTypewriter

RSCG – NTypewriter
 
 

name NTypewriter
nuget https://www.nuget.org/packages/NTypewriter.SourceGenerator
link https://github.com/NeVeSpl/NTypewriter
author NeVeSpl

Generating code with a template from classes in project

 

This is how you can use NTypewriter .

The code that you start with is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<Project Sdk="Microsoft.NET.Sdk">
 
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
 
  <ItemGroup>
    <None Remove="test.nt" />
  </ItemGroup>
 
  <ItemGroup>
    <AdditionalFiles Include="test.nt" />
  </ItemGroup>
 
  <ItemGroup>
    <PackageReference Include="NTypewriter.SourceGenerator" Version="0.5.9" />
  </ItemGroup>
 
    <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
</Project>

The code that you will use is

1
2
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
1
2
3
4
5
namespace DemoTemplateConsole;
public class PersonModel
{
    public int Name { get; set; }
}

 

The code that is generated is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
// NTypewriter.SourceGenerator                      0.5.9.0  C:\Users\ignat\AppData\Local\Temp\VBCSCompiler\AnalyzerAssemblyLoader\f44f8d8546d2454b92ff0e62b6eaea10\4a40c9db-c376-41d2-8a7c-26eda7296396\NTypewriter.SourceGenerator.dll NTypewriter.SourceGenerator, Version=0.5.9.0, Culture=neutral, PublicKeyToken=null
// NTypewriter                                      0.5.9.0  C:\Users\ignat\AppData\Local\Temp\NTSG\NTypewriter.v0.5.9.0.dll NTypewriter, Version=0.5.9.0, Culture=neutral, PublicKeyToken=686471615d7a8f08
// NTypewriter.CodeModel                            0.5.9.0  C:\Users\ignat\AppData\Local\Temp\NTSG\NTypewriter.CodeModel.v0.5.9.0.dll NTypewriter.CodeModel, Version=0.5.9.0, Culture=neutral, PublicKeyToken=9bd097c4961606db
// NTypewriter.CodeModel.Functions                  0.5.9.0  C:\Users\ignat\AppData\Local\Temp\NTSG\NTypewriter.CodeModel.Functions.v0.5.9.0.dll NTypewriter.CodeModel.Functions, Version=0.5.9.0, Culture=neutral, PublicKeyToken=64a6b4cdbb438ab5
// NTypewriter.CodeModel.Roslyn                     0.5.9.0  C:\Users\ignat\AppData\Local\Temp\NTSG\NTypewriter.CodeModel.Roslyn.v0.5.9.0.dll NTypewriter.CodeModel.Roslyn, Version=0.5.9.0, Culture=neutral, PublicKeyToken=81d8e46ee60c9c4c
// NTypewriter.Editor.Config                        0.5.9.0  C:\Users\ignat\AppData\Local\Temp\NTSG\NTypewriter.Editor.Config.v0.5.9.0.dll NTypewriter.Editor.Config, Version=0.5.9.0, Culture=neutral, PublicKeyToken=b9f8710003231974
// NTypewriter.Runtime                              0.5.9.0  C:\Users\ignat\AppData\Local\Temp\NTSG\NTypewriter.Runtime.v0.5.9.0.dll NTypewriter.Runtime, Version=0.5.9.0, Culture=neutral, PublicKeyToken=4fac57df20922078
// Scriban.Signed                                   5.0.0.0  C:\Users\ignat\AppData\Local\Temp\NTSG\Scriban.Signed.v5.10.0.0.dll Scriban.Signed, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5675fb69b15f2433
// System.Text.Json                                 6.0.0.0  C:\Users\ignat\AppData\Local\Temp\NTSG\System.Text.Json.v6.0.0.0.dll System.Text.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
// System                                           4.0.0.0  C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// Microsoft.CodeAnalysis                           4.14.0.0  C:\Program Files\Microsoft Visual Studio\2022\Preview\MSBuild\Current\Bin\Roslyn\Microsoft.CodeAnalysis.dll Microsoft.CodeAnalysis, Version=4.14.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Microsoft.CodeAnalysis.CSharp                    4.14.0.0  C:\Program Files\Microsoft Visual Studio\2022\Preview\MSBuild\Current\Bin\Roslyn\Microsoft.CodeAnalysis.CSharp.dll Microsoft.CodeAnalysis.CSharp, Version=4.14.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Microsoft.CodeAnalysis.Scripting                 4.0.0.0  C:\Users\ignat\AppData\Local\Temp\NTSG\Microsoft.CodeAnalysis.Scripting.v4.0.1.0.dll Microsoft.CodeAnalysis.Scripting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Microsoft.CodeAnalysis.CSharp.Scripting          4.0.0.0  C:\Users\ignat\AppData\Local\Temp\NTSG\Microsoft.CodeAnalysis.CSharp.Scripting.v4.0.1.0.dll Microsoft.CodeAnalysis.CSharp.Scripting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Microsoft.CodeAnalysis.Workspaces                4.0.0.0  C:\Users\ignat\AppData\Local\Temp\NTSG\Microsoft.CodeAnalysis.Workspaces.v4.0.1.0.dll Microsoft.CodeAnalysis.Workspaces, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// CurrentDomain: VBCSCompiler.exe
1
2
3
4
5
6
7
// NTypewriter.SourceGenerator v0.5.9.0
// total runs     : 4, total renders : 4
// touch file     : D:\gth\RSCG_Examples\v2\rscg_examples\NTypewriter\src\DemoTemplate\DemoTemplateConsole\bin\Debug\net9.0\.touch
// log file       : D:\gth\RSCG_Examples\v2\rscg_examples\NTypewriter\src\DemoTemplate\DemoTemplateConsole\bin\Debug\net9.0\DemoTemplateConsole.ntsg.log                   
// last build     : 2/15/2025 5:39:39 PM
// last *.nt edit : 2/15/2025 5:39:31 PM
// last render    : 2/15/2025 5:39:39 PM

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/NTypewriter

RSCG – rscg_Interface_to_null_object

RSCG – rscg_Interface_to_null_object
 
 

name rscg_Interface_to_null_object
nuget https://www.nuget.org/packages/rscg_Interface_to_null_object/
https://www.nuget.org/packages/rscg_Interface_to_null_object_common
link https://github.com/ignatandrei/rscg_Interface_to_null_object/
author Andrei Ignat

Generate null objects for interfaces

 

This is how you can use rscg_Interface_to_null_object .

The code that you start with is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<Project Sdk="Microsoft.NET.Sdk">
 
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
 
  <ItemGroup>
    <PackageReference Include="rscg_Interface_to_null_object" Version="2025.120.1832" OutputItemType="Analyzer" ReferenceOutputAssembly="false"  />
    <PackageReference Include="rscg_Interface_to_null_object_common" Version="2025.120.1832" />
  </ItemGroup>
 
    <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
</Project>

The code that you will use is

01
02
03
04
05
06
07
08
09
10
11
12
using NullInterface;
 
Console.WriteLine("Hello, World!");
 
Console.WriteLine("Hello, World!");
IDepartment department = new Department_null();
department.Name = "IT";
IEmployee employee = new Employee_null();
employee.FirstName = "Andrei";
employee.Department = department;
Console.WriteLine(employee.FirstName);
Console.WriteLine(employee.Department.Name);
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
using InterfaceToNullObject;
 
namespace NullInterface;
[ToNullObject]
public interface IEmployee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public IDepartment Department { get; set; }
    public string GetFullName();
 
    public string GetFullNameAndDepartment(string separator);
    public bool MoveEmployeeToDepartment(IDepartment department);
 
}
1
2
3
4
5
6
7
8
9
namespace NullInterface;
 
using InterfaceToNullObject;
 
[ToNullObject]
public interface IDepartment
{
    public string Name { get; set; }
}

 

The code that is generated is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
// <auto-generated/>
namespace Generated.NullInterface
{
    public static class TheAssemblyInfo
    {
         
        public static readonly System.DateTime DateGeneratedUTC ;
        public const string AssemblyName = "NullInterface";
        public const string GeneratedNameNice = "Olga Tokarczuk is feeling quick-witted in Quito";
        public const string GeneratedNameSmall = "quick-witted-Olga Tokarczuk";
        public const string GeneratedName = "quick-witted-Olga Tokarczuk-Quito";
        static TheAssemblyInfo(){
            DateGeneratedUTC = System.DateTime.ParseExact("2025-02-15 15:42:10", "yyyy-MM-dd HH:mm:ss", null);
        }
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// <auto-generated>
    //     This code was generated by a tool :rscg_Interface_to_null_object
    //     Runtime Version: Jaroslav Seifert is feeling cheap in Belmopan
    //     DateOfTool : 2025-01-20 16:33:43
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
//------------------------------------------------------------------------------
/// <summary>
    /// This static partial class contains extension methods for sorting collections of IDepartment objects.
    /// </summary>
 
 #nullable enable
 #pragma warning disable CS8603
 #pragma warning disable CS8625
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.CodeDom.Compiler.GeneratedCode("GeneratorName","2025.10120.11633.143")]
public partial class Department_null : global::NullInterface.IDepartment
{
 
        public virtual string Name { get; set; } = default(string);
     
}
 
#nullable restore
#pragma warning restore CS8603
#pragma warning restore CS8625
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// <auto-generated>
    //     This code was generated by a tool :rscg_Interface_to_null_object
    //     Runtime Version: Jaroslav Seifert is feeling cheap in Belmopan
    //     DateOfTool : 2025-01-20 16:33:43
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
//------------------------------------------------------------------------------
/// <summary>
    /// This static partial class contains extension methods for sorting collections of IEmployee objects.
    /// </summary>
 
 #nullable enable
 #pragma warning disable CS8603
 #pragma warning disable CS8625
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.CodeDom.Compiler.GeneratedCode("GeneratorName","2025.10120.11633.143")]
public partial class Employee_null : global::NullInterface.IEmployee
{
 
        public virtual string FirstName { get; set; } = default(string);
     
        public virtual string LastName { get; set; } = default(string);
     
        public virtual NullInterface.IDepartment Department { get; set; } = default(NullInterface.IDepartment);
     
        public virtual string GetFullName() { return default(string); }
     
        public virtual string GetFullNameAndDepartment(string separator) { return default(string); }
     
        public virtual bool MoveEmployeeToDepartment(global::NullInterface.IDepartment department) { return default(bool); }
     
}
 
#nullable restore
#pragma warning restore CS8603
#pragma warning restore CS8625

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg_Interface_to_null_object

RSCG – Larcanum.GitInfo

RSCG – Larcanum.GitInfo
 
 

name Larcanum.GitInfo
nuget https://www.nuget.org/packages/Larcanum.GitInfo/
link https://github.com/lord-executor/Larcanum.GitInfo
author

Generates GitInfo data from the current environment.

 

This is how you can use Larcanum.GitInfo .

The code that you start with is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<Project Sdk="Microsoft.NET.Sdk">
 
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
     
    <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
     
    <ItemGroup>
      <PackageReference Include="Larcanum.GitInfo" Version="1.1.0">
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        <PrivateAssets>all</PrivateAssets>
      </PackageReference>
    </ItemGroup>
</Project>

The code that you will use is

1
2
3
4
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
Console.WriteLine($"Version: {DemoGit.GitInfo.Branch}");
Console.WriteLine($"Version: {DemoGit.GitInfo.CommitDate}");

 

The code that is generated is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// <auto-generated />
 
// Generator Context
// ProjectDir: D:\gth\RSCG_Examples\v2\rscg_examples\Larcanum.GitInfo\src\DemoGit\DemoGit\
// GitInfoNamespace: DemoGit
// GitInfoGlobalNamespace: False
// GitInfoGitBin: git
// GitInfoVersionRegex: v?(?<VERSION>(?<MAJOR>\d+)\.(?<MINOR>\d+)(?:\.(?<PATCH>\d+))?(?:[-+](?<LABEL>[\dA-Za-z\-\.]+))?)$
// GitInfoGenerateAssemblyVersion: True
// GitInfoDebug: False
// GitPath: C:\Program Files\Git\cmd\git.exe
// GitVersion: git version 2.42.0.windows.2
// GitRoot: D:/gth/RSCG_Examples
// GitFingerprint: vPureDI3-7-g5308331d7
// Timestamp: 2025-01-18T15:18:22.4819389+02:00
 
[assembly: System.Reflection.AssemblyVersion("1.0.0.0")]
[assembly: System.Reflection.AssemblyFileVersion("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersion("vPureDI3-7-g5308331d7")]
 
 
namespace DemoGit;
 
/// <summary>Provides access to the git information for the current assembly.</summary>
internal partial class GitInfo
{
    public const bool IsDirty = false;
 
    public const string Branch = @"Larcanum.GitInfo";
 
    public const string CommitShortHash = @"5308331d7";
 
    public const string CommitHash = @"5308331d78c3674c7354749ac82d7b1199277997";
 
    public const string CommitDate = @"2024-12-24T19:19:30+02:00";
 
    public const string Tag = @"vPureDI3-7-g5308331d7";
 
    public const string DotNetVersion = @"1.0.0.0";
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Larcanum.GitInfo

openAPISwaggerUI–part 4–adding tests

This is how I made

https://nuget.org/packages/OpenAPISwaggerUI in order to see the UI for an ASP.NET 9 project.

And hey, if you have any feedback, don’t be shy! Drop by https://github.com/ignatandrei/openAPISwaggerUI/ and let me know.

For testing, I have created a new ASP.NET Core 9 project that can be used to run

1
2
3
4
app.MapOpenApi();
app.UseOpenAPISwaggerUI();
 
public partial class Program { }

And I want to see that /swagger endpoint exists . And more, to have pictures with the different UIs.

The WebApplicationFactory is used to create a test server that can be used to test the application. But I need more – to have a real server that can be used to test the application.

I have found this link that show how to start Kestrel server in a test project : https://danieldonbavand.com/2022/06/13/using-playwright-with-the-webapplicationfactory-to-test-a-blazor-application/

And now the code for having the pre-requisites for testing is as easy as pie.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
static CustomWebApplicationFactory factory;
[AssemblyInitialize]
public static void AssemblyInit(TestContext context)
{
     
    var exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
    if (exitCode != 0)
    {
        throw new Exception($"Playwright exited with code {exitCode}");
    }
    factory = new ();
    var url = factory.ServerAddress;
    Console.WriteLine($"Server address: {url}");
}

And we can test the weatherforecast endpoint – because who doesn’t love knowing the weather, right?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
[TestMethod]
public async Task TestWeHaveRealWebServer()
{
     
    using var client = factory.CreateDefaultClient();
    var response = await client.GetAsync("/weatherforecast");
    response.EnsureSuccessStatusCode();
    var baseAddress = factory.ServerAddress;
    if(!baseAddress.EndsWith("/"))
    {
        baseAddress += "/";   
    }
    using var playwright = await Playwright.CreateAsync();
    var request = await playwright.APIRequest.NewContextAsync();
         
    var response1 = await request.GetAsync(baseAddress+"weatherforecast");
    Assert.IsTrue(response1.Ok);
}

And to test the endpoints for my library , OpenAPISwaggerUI

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[TestMethod]
public async Task TestIntegrationWorks()
{
 
    var baseAddress = factory.ServerAddress;
    if (!baseAddress.EndsWith("/"))
    {
        baseAddress += "/";
    }
    using var playwright = await Playwright.CreateAsync();
    var request = await playwright.APIRequest.NewContextAsync();
 
    await using var browser = await playwright.Chromium.LaunchAsync();
    var context = await browser.NewContextAsync(new()
    {
        //RecordVideoDir = curDirVideos
    });
    var page = await browser.NewPageAsync();
    var pageSwagger = await page.GotoAsync(baseAddress + "swagger");
    await page.ScreenshotAsync(new PageScreenshotOptions { Path = "swagger.png" });
    var content= await page.ContentAsync();
    var hrefs = await page.Locator("a").AllAsync();
     
    Assert.IsTrue(hrefs.Count > 0);
    foreach (var li in hrefs)
    {
        var text= await li.TextContentAsync();
        var href = await li.GetAttributeAsync("href");
        ArgumentNullException.ThrowIfNull(href);
        if(href.StartsWith("/"))
        {
            href =  href[1..];
        }
        var pageNew = await browser.NewPageAsync();
        await pageNew.GotoAsync(baseAddress+ href);
        await pageNew.WaitForLoadStateAsync(LoadState.NetworkIdle);
        await pageNew.ScreenshotAsync(new PageScreenshotOptions { Path = $"{text}.png" });
 
 
    }
}

openAPISwaggerUI–part 3–add UI for all

This is how I made

https://nuget.org/packages/OpenAPISwaggerUI in order to see the UI for an ASP.NET 9 project.

And hey, if you have any feedback, don’t be shy! Drop by https://github.com/ignatandrei/openAPISwaggerUI/ and let me know.

Now I want the users of my ASP.NET 9 project to have a buffet of Swagger UIs (Swashbuckle, Redoc, Scalar, NSwag, VisualAutomation) and let them pick their favorite flavor.

The master plan? Create an endpoint (let’s call it /swagger) that showcases all these UIs like a proud parent at a talent show.

But wait, there’s more! I want to sprinkle in some custom info – project version, UI links, and other goodies.

Enter the RazorBlade NuGet package, my trusty sidekick for crafting a Razor page.

So I used the RazorBlade nuget package to create a Razor page .

1
2
3
<ItemGroup>
    <PackageReference Include="RazorBlade" Version="0.7.0" PrivateAssets="all" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
</ItemGroup>

And voilà, the SwaggerData.cshtml Razor page is born:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@using OpenAPISwaggerUI
@inherits RazorBlade.PlainTextTemplate<SwaggerUIData>
 
<html>
<body>
    <h1>Swagger UI</h1>
    <h2>
        <a href="@Model.SwaggerEndpoint" target="_blank">SwaggerEndpoint</a>
    </h2>
    <ul>
        <li>
            <a href="@Model.Swashbuckle" target="_blank">Swashbuckle</a>
        </li>
        <li>
            <a href="@Model.NSwag" target="_blank">NSwag</a>
        </li>
        <li>
            <a href="@Model.ReDoc" target="_blank">Redoc</a>
        </li>
        <li>
            <a href="@Model.Scalar" target="_blank">Scalar</a>
        </li>
        <li>
            <a href="@Model.Blockly" target="_blank">VisualAutomation</a>
        </li>
    </ul>
    <small>
        Generated by <a href="https://www.nuget.org/packages/OpenAPISwaggerUI" target="_blank"> @Model.AssemblyName : @Model.MyName</a>
    </small>
</body>
</html>

openAPISwaggerUI–part 2 – add ui for all

This is how I made

https://nuget.org/packages/OpenAPISwaggerUI in order to see the UI for an ASP.NET 9 project.

And hey, if you have any feedback, don’t be shy! Drop by https://github.com/ignatandrei/openAPISwaggerUI/ and let me know.

Step one in this epic quest: add all the mystical references (a.k.a. NuGet packages) to the project file.

1
2
3
4
5
6
7
8
9
<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
    <PackageReference Include="NetCore2Blockly" Version="9.2024.1206.813" />
    <PackageReference Include="NSwag.AspNetCore" Version="14.2.0" />
    <PackageReference Include="RSCG_NameGenerator" Version="2024.26.8.2002" PrivateAssets="all" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
    <PackageReference Include="Scalar.AspNetCore" Version="1.2.56" />
    <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="7.2.0" />
    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="7.2.0" />
</ItemGroup>

Next, I had to figure out how to register these mystical packages to reveal the UI

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public static WebApplication UseOpenAPISwaggerUI(this WebApplication app)
{
      
//goto /swagger-Swashbuckle
app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint("/openapi/v1.json", "v1");
    options.RoutePrefix = "swagger-Swashbuckle";
});
//scalar
//goto swagger-scalar/v1
app.MapScalarApiReference(opt =>
{
    opt.EndpointPathPrefix = "/swagger-scalar/{documentName}";
});
//redoc
//goto /api-docs
app.UseReDoc(options =>
{
    options.SpecUrl("/openapi/v1.json");
    options.RoutePrefix = "swagger-redoc";
});
 
//goto /nswag-swagger
app.UseSwaggerUi(options =>
{
    options.DocumentPath = "/openapi/v1.json";
    options.Path = "/swagger-nswag";
});
//goto /blocklyautomation
app.UseBlocklyUI(app.Environment);
app.UseBlocklyAutomation();
}

After this it was simple to use the extension in program.cs

1
2
app.MapOpenApi();
app.UseOpenAPISwaggerUI();

openAPISwaggerUI–part 1- idea

In .NET 9, Microsoft decided to play a little game of “Hide and Seek” with OpenAPI / Swagger JSON generation, leaving the UI part for us to figure out.

So, how do we choose the best UI for our project without turning it into a guessing game?

Well, I thought, why not create a project that lets you try all the options at once? It’s like a buffet, but for UIs!

You can grab it from https://nuget.org/packages/OpenAPISwaggerUI or install it with `dotnet add package OpenAPISwaggerUI`.

The UI I have found are from

Swashbuckle

NSwag

Redoc

Scalar

Visual Automation ( disclosure  : a project of mine )

And hey, if you have any feedback, don’t be shy! Drop by https://github.com/ignatandrei/openAPISwaggerUI/ and let me know.

[Interface2NullObject]Debugger and Converter–part 5

 

It will be interesting to see the Null Object in the debugger with properties generated from interface -see  https://www.nuget.org/packages/rscg_Interface_to_null_object

 

This is not very difficult to generate once you have the interface with properties

The code for generating

01
02
03
04
05
06
07
08
09
10
11
12
13
14
public string DebuggerDisplay() 
{
    StringBuilder sb = new StringBuilder("[System.Diagnostics.DebuggerDisplay(");
    sb.Append("\"");
    foreach (var item in props)
    {
        sb.Append(item.Name);
        sb.Append(" = {");
        sb.Append(item.Name);
        sb.Append("} " );
    }
    sb.Append("\")]");
    return sb.ToString();
}

 

and the code generated is

 

1
2
[System.Diagnostics.DebuggerDisplay("FirstName = {FirstName} LastName = {LastName} Department = {Department} ")]
public partial class Employee_null : global::IntegrationConsole.IEmployee

 

More interesting is to have a converter in order to obtain from the JSON string the interface, not the object .

 

The code for generating is

 

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
public class @(Model.Name + "Converter") : System.Text.Json.Serialization.JsonConverter<@(Model.FullName)>
    {
    public override @Model.FullName Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options)
    {
    // Deserialize the JSON to the concrete type @Model.Name
    return System.Text.Json.JsonSerializer.Deserialize<@nameClass>
        (ref reader, options);
        }
 
        public override void Write(System.Text.Json.Utf8JsonWriter writer, @Model.FullName value, System.Text.Json.JsonSerializerOptions options)
        {
        // Serialize the concrete type @Model.Name
        System.Text.Json.JsonSerializer.Serialize(writer, (@nameClass)value, options);
        }
        }

and the code generated is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
//serialize and deserialize
var empString = JsonSerializer.Serialize(employee);
Console.WriteLine(empString);
//deserialize
 
var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true,
    DefaultBufferSize = 128
};
options.Converters.Add(new IDepartmentConverter());
options.Converters.Add(new IEmployeeConverter());
 
var emp2 = JsonSerializer.Deserialize<IEmployee>(empString,options);
ArgumentNullException.ThrowIfNull(emp2);
Console.WriteLine(emp2.FirstName);
Console.WriteLine(emp2.Department.Name);
Debug.Assert(emp2.FirstName == "Andrei");

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.