Category: RSCG

RSCG – RSCG_ExportDiagram

RSCG – RSCG_ExportDiagram
 
 

name RSCG_ExportDiagram
nuget https://github.com/ignatandrei/RSCG_ExportDiagram
link RSCG_ExportDiagram
author AndreiIgnat

Generating diagram for relation classes within referenced project

 

This is how you can use RSCG_ExportDiagram .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

	<ItemGroup>
		<PackageReference Include="RSCG_ExportDiagram" Version="2024.810.832" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
	</ItemGroup>
	<ItemGroup>
		<CompilerVisibleProperty Include="RSCG_ExportDiagram_OutputFolder" />
		<CompilerVisibleProperty Include="RSCG_ExportDiagram_Exclude" />
	</ItemGroup>
	<ItemGroup>
	  <ProjectReference Include="..\Person\Person.csproj" />
	</ItemGroup>
	<PropertyGroup>
		<RSCG_ExportDiagram_OutputFolder>obj/GX/</RSCG_ExportDiagram_OutputFolder>
		<RSCG_ExportDiagram_Exclude></RSCG_ExportDiagram_Exclude>
	</PropertyGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using Person;

internal class Program
{
    private static void Main(string[] args)
    {
        PersonData person = new ();
        person.Name = "Andrei Ignat";
        Console.WriteLine(person.Name);
    }
}


namespace Person;

public class PersonData
{
    public string Name { get; set; }
    public int Age { get; set; }
}




 

The code that is generated is


//JSONFolder=obj/GX/
//projectDir=D:\gth\RSCG_Examples\v2\rscg_examples\RSCG_ExportDiagram\src\DiagramDemo\DiagramDemoConsole\
//projectName=DiagramDemoConsole
//excludeData=
file class Program_References_1
{
    public Program_References_1()
{
     

// Method Main has following external references
// Person.PersonData..ctor
//Person.PersonData.Name

}
}

Code and pdf at

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

RSCG – ServiceScan.SourceGenerator

RSCG – ServiceScan.SourceGenerator
 
 

name ServiceScan.SourceGenerator
nuget https://www.nuget.org/packages/ServiceScan.SourceGenerator/
link https://github.com/Dreamescaper/ServiceScan.SourceGenerator
author Oleksandr Liakhevych

Generating service collection / DI registration

 

This is how you can use ServiceScan.SourceGenerator .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
	<ItemGroup>
	  <PackageReference Include="ServiceScan.SourceGenerator" Version="1.1.2">
	    <PrivateAssets>all</PrivateAssets>
	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
	  </PackageReference>
		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
	</ItemGroup>
</Project>


The code that you will use is


using InjectDemo;
using Microsoft.Extensions.DependencyInjection;
var sc=new ServiceCollection();
sc.AddMyServices();
var sp=sc.BuildServiceProvider();
var con = sp.GetService(typeof(Database)) as IDatabase;
ArgumentNullException.ThrowIfNull(con);
con.Open();



public static partial class MyServiceProvider
{
    [ServiceScan.SourceGenerator.GenerateServiceRegistrations(AssignableTo = typeof(Database),AsSelf =true, Lifetime = ServiceLifetime.Scoped)]

    [ServiceScan.SourceGenerator.GenerateServiceRegistrations(AssignableTo = typeof(IDatabase), Lifetime = ServiceLifetime.Scoped)]
    public static partial IServiceCollection AddMyServices(this IServiceCollection services)
    ;
}


namespace InjectDemo;

partial class Database : IDatabase
{
    private readonly IDatabase con;

    public Database(IDatabase con)
    {
        this.con = con;
    }
    public void Open()
    {
        Console.WriteLine($"open from database");
        con.Open();
    }

}





namespace InjectDemo;

public partial class DatabaseCon:IDatabase
{
    public string? Connection { get; set; }
    public void Open()
    {
        Console.WriteLine("open from database con" );
    }
}



 

The code that is generated is

#nullable enable

using System;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;

namespace ServiceScan.SourceGenerator;

[Conditional("CODE_ANALYSIS")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
internal class GenerateServiceRegistrationsAttribute : Attribute
{
    /// <summary>
    /// Set the assembly containing the given type as the source of types to register.
    /// If not specified, the assembly containing the method with this attribute will be used.
    /// </summary>
    public Type? FromAssemblyOf { get; set; }

    /// <summary>
    /// Set the type that the registered types must be assignable to.
    /// Types will be registered with this type as the service type,
    /// unless <see cref="AsImplementedInterfaces"/> or <see cref="AsSelf"/> is set.
    /// </summary>
    public Type? AssignableTo { get; set; }

    /// <summary>
    /// Set the lifetime of the registered services.
    /// <see cref="ServiceLifetime.Transient"/> is used if not specified.
    /// </summary>
    public ServiceLifetime Lifetime { get; set; }

    /// <summary>
    /// If set to true, types will be registered as implemented interfaces instead of their actual type.
    /// </summary>
    public bool AsImplementedInterfaces { get; set; }

    /// <summary>
    /// If set to true, types will be registered with their actual type.
    /// It can be combined with <see cref="AsImplementedInterfaces"/>, in that case implemeted interfaces will be
    /// "forwarded" to "self" implementation.
    /// </summary>
    public bool AsSelf { get; set; }

    /// <summary>
    /// Set this value to filter the types to register by their full name. 
    /// You can use '*' wildcards.
    /// You can also use ',' to separate multiple filters.
    /// </summary>
    /// <example>Namespace.With.Services.*</example>
    /// <example>*Service,*Factory</example>
    public string? TypeNameFilter { get; set; }
}
using Microsoft.Extensions.DependencyInjection;



public static partial class MyServiceProvider
{
    public static partial IServiceCollection AddMyServices(this IServiceCollection services)
    {
        return services
            .AddScoped<InjectDemo.Database, InjectDemo.Database>()
            .AddScoped<InjectDemo.IDatabase, InjectDemo.Database>()
            .AddScoped<InjectDemo.IDatabase, InjectDemo.DatabaseCon>();
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/ServiceScan.SourceGenerator

RSCG – ThisAssembly.Strings

RSCG – ThisAssembly.Strings
 
 

name ThisAssembly.Strings
nuget https://www.nuget.org/packages/ThisAssembly.Strings/
link https://github.com/devlooped/ThisAssembly
author Daniel Cazzulino

generating code from resx files

 

This is how you can use ThisAssembly.Strings .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="ThisAssembly.Strings" Version="1.4.3">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <Compile Update="Demo.Designer.cs">
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
      <DependentUpon>Demo.resx</DependentUpon>
    </Compile>
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Update="Demo.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Demo.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


Console.WriteLine(ThisAssembly.Strings.PersonName("Andrei Ignat"));



<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="PersonName" xml:space="preserve">
    <value>The person name is {0}</value>
    <comment>the person name</comment>
  </data>
</root>

 

The code that is generated is

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     ThisAssembly.Strings: 1.4.3
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Globalization;

partial class ThisAssembly
{
    public static partial class Strings
    {
        /// <summary>
        /// the person name
        /// </summary>
        public static string PersonName(object arg0) => string.Format(CultureInfo.CurrentCulture, Strings.GetResourceManager("StringsDemo.Demo").GetString("PersonName"), arg0);
    }
}
using System.Collections.Concurrent;
using System.Resources;
using System.Runtime.CompilerServices;

/// <summary>
/// Provides access to the current assembly information as pure constants, 
///  without requiring reflection.
/// </summary>
partial class ThisAssembly
{
    /// <summary>
    /// Access the strings provided by resource files in the project.
    /// </summary>
    [CompilerGenerated]
    public static partial class Strings
    {
        static ConcurrentDictionary<string, ResourceManager> resourceManagers = new ConcurrentDictionary<string, ResourceManager>();

        static ResourceManager GetResourceManager(string resourceName)
            => resourceManagers.GetOrAdd(resourceName, name => new ResourceManager(name, typeof(Strings).Assembly));
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/ThisAssembly.Strings

RSCG – ThisAssembly.Metadata

RSCG – ThisAssembly.Metadata    

name ThisAssembly.Metadata
nuget https://www.nuget.org/packages/ThisAssembly.Metadata/
link https://github.com/devlooped/ThisAssembly
author Daniel Cazzulino

Generating code from assembly metadata

 

This is how you can use ThisAssembly.Metadata .

The code that you start with is

  <Project Sdk="Microsoft.NET.Sdk">    <PropertyGroup>     <OutputType>Exe</OutputType>     <TargetFramework>net8.0</TargetFramework>     <ImplicitUsings>enable</ImplicitUsings>     <Nullable>enable</Nullable>   </PropertyGroup> 	<ItemGroup> 		<AssemblyMetadata Include="MyName" Value="Andrei" /> 	</ItemGroup> 	<ItemGroup> 	  <PackageReference Include="ThisAssembly.Metadata" Version="1.4.3"> 	    <PrivateAssets>all</PrivateAssets> 	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> 	  </PackageReference> 	</ItemGroup> 	<PropertyGroup> 		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> 		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> 	</PropertyGroup> </Project>   

The code that you will use is

  [assembly: System.Reflection.AssemblyMetadataAttribute("Name", "Test")]  Console.WriteLine(ThisAssembly.Metadata.Name); Console.WriteLine(ThisAssembly.Metadata.MyName);   

  The code that is generated is

 //------------------------------------------------------------------------------ // <auto-generated> //     This code was generated by a tool. // //     Changes to this file may cause incorrect behavior and will be lost if //     the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------  using System.CodeDom.Compiler; using System.Runtime.CompilerServices;  /// <summary> /// Provides access to the current assembly information as pure constants,  ///  without requiring reflection. /// </summary> partial class ThisAssembly {     /// <summary>     /// Gets the assembly metadata.     /// </summary>     [GeneratedCode("ThisAssembly.Metadata", "1.4.3")]     [CompilerGenerated]     public static partial class Metadata     {         /// <summary>Name = Test</summary>         public const string Name =  """ Test """;          /// <summary>MyName = Andrei</summary>         public const string MyName =  """ Andrei """;      } } 

Code and pdf at https://ignatandrei.github.io/RSCG_Examples/v2/docs/ThisAssembly.Metadata

RSCG – Pekspro.BuildInformationGenerator

RSCG – Pekspro.BuildInformationGenerator    

name Pekspro.BuildInformationGenerator
nuget https://www.nuget.org/packages/Pekspro.BuildInformationGenerator/
link https://github.com/pekspro/BuildInformationGenerator
author pekspro

adding git build information

  

This is how you can use Pekspro.BuildInformationGenerator .

The code that you start with is


<project sdk="Microsoft.NET.Sdk">

  <propertygroup>
    <outputtype>Exe</outputtype>
    <targetframework>net8.0</targetframework>
    <implicitusings>enable</implicitusings>
    <nullable>enable</nullable>
  </propertygroup>

  <itemgroup>
    <packagereference version="0.2.0" include="Pekspro.BuildInformationGenerator">
  </packagereference>
	<propertygroup>
		<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
		<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
	</propertygroup>
</itemgroup>


The code that you will use is


using BuildInfo;

Console.WriteLine(MyBuildInfo.Git.CommitId);
Console.WriteLine(MyBuildInfo.Git.Branch);
Console.WriteLine(MyBuildInfo.AssemblyVersionString);




using Pekspro.BuildInformationGenerator;

namespace BuildInfo;
[BuildInformation(AddBuildTime = true, 
    AddGitCommitId = true,
    AddAssemblyVersion = true,
    AddDotNetSdkVersion = true,
    AddGitBranch = true,
    AddLocalBuildTime= true,
    AddOSVersion = true,    
    FakeIfDebug =false,
    FakeIfRelease =false)]
partial class MyBuildInfo
{
}


   The code that is generated is

//---------------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Pekspro.BuildInformationGenerator source generator.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//---------------------------------------------------------------------------------------

namespace BuildInfo
{
    /// <summary>
    /// Build information.
    /// </summary>
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Pekspro.BuildInformationGenerator", "0.2.0")]
    static partial class MyBuildInfo
    {

        /// <summary>
        /// Build time: 2024-07-18 19:57:53
        /// Value was taken from the system clock.
        /// </summary>
        public static readonly global::System.DateTime BuildTime = new global::System.DateTime(638569294731432248L, global::System.DateTimeKind.Utc);

        /// <summary>
        /// Local build time: 2024-07-18 22:57:53 (+03:00)
        /// Value was taken from the system clock.
        /// </summary>
        public static readonly global::System.DateTimeOffset LocalBuildTime = new global::System.DateTimeOffset(638569402731432248L, new global::System.TimeSpan(108000000000));

        /// <summary>
        /// Build information related to git.
        /// </summary>
        static public partial class Git
        {

            /// <summary>
            /// The commit id in git at the time of build.
            /// Value was taken from the AssemblyInformationalVersion attribute.
            /// </summary>
            public const string CommitId = "51a6dd67bbe091af607870fd80a52ea54d249e47";

            /// <summary>
            /// The short commit id in git at the time of build.
            /// Value was taken from the AssemblyInformationalVersion attribute.
            /// </summary>
            public const string ShortCommitId = "51a6dd67";

            /// <summary>
            /// The git branch used at build time.
            /// Value was taken from the git branch command.
            /// </summary>
            public const string Branch = "278-httpsgithubcompeksprobuildinformationgenerator";

        }

        /// <summary>
        /// Version of the assembly.
        /// Value was taken from assembly version attribute.
        /// </summary>
        public const string AssemblyVersionString = "1.0.0.0";

        /// <summary>
        /// OS version of the building machine.
        /// Value was taken from Environment.OSVersion.
        /// </summary>
        public const string OSVersion = "Microsoft Windows NT 6.2.9200.0";

        /// <summary>
        /// .NET SDK version used at build time.
        /// Value was taken from the dotnet --version command.
        /// </summary>
        public const string DotNetSdkVersion = "8.0.303";

    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.BuildInformationGenerator

RSCG – ThisAssembly.Constants

RSCG – ThisAssembly.Constants    

name ThisAssembly.Constants
nuget https://www.nuget.org/packages/ThisAssembly.Constants/
link https://github.com/devlooped/ThisAssembly
author Daniel Cazzulino

Generating Constants from csproj

 

This is how you can use ThisAssembly.Constants .

The code that you start with is

  <Project Sdk="Microsoft.NET.Sdk">    <PropertyGroup>     <OutputType>Exe</OutputType>     <TargetFramework>net8.0</TargetFramework>     <ImplicitUsings>enable</ImplicitUsings>     <Nullable>enable</Nullable>   </PropertyGroup>    <ItemGroup> 	  <Constant Include="TimeOut" Value="100" Comment="Test" />     <PackageReference Include="ThisAssembly.Constants" Version="1.4.3">       <PrivateAssets>all</PrivateAssets>       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>     </PackageReference>   </ItemGroup> 	<PropertyGroup> 		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> 		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> 	</PropertyGroup> </Project>   

The code that you will use is

  Console.WriteLine(ThisAssembly.Constants.TimeOut);  

  The code that is generated is

 //------------------------------------------------------------------------------ // <auto-generated> //     This code was generated by a tool. // //     ThisAssembly.Constants: 1.4.3 // //     Changes to this file may cause incorrect behavior and will be lost if //     the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ using System; using System.Globalization;  partial class ThisAssembly {     public static partial class Constants     {         /// <summary>         /// Test         /// </summary>         public const string TimeOut = """ 100 """;     } } 

Code and pdf at https://ignatandrei.github.io/RSCG_Examples/v2/docs/ThisAssembly.Constants

RSCG – JKToolKit.TemplatePropertyGenerator

RSCG – JKToolKit.TemplatePropertyGenerator    

name JKToolKit.TemplatePropertyGenerator
nuget https://www.nuget.org/packages/JKToolKit.TemplatePropertyGenerator/
link https://github.com/JKamsker/JKToolKit.TemplatePropertyGenerator
author Jonas Kamsker

String templating for a class

  

This is how you can use JKToolKit.TemplatePropertyGenerator .

The code that you start with is


<project sdk="Microsoft.NET.Sdk">

  <propertygroup>
    <outputtype>Exe</outputtype>
    <targetframework>net8.0</targetframework>
    <implicitusings>enable</implicitusings>
    <nullable>enable</nullable>
  </propertygroup>

  <itemgroup>
    <packagereference version="0.0.4" include="JKToolKit.TemplatePropertyGenerator">
  </packagereference>
	<propertygroup>
		<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
		<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
	</propertygroup>
</itemgroup>


The code that you will use is


using SimpleTemplate;

Person person = new();
person.FirstName = "Andrei";
person.LastName = "Ignat";
Console.WriteLine(new Person.HelloClass().Format(person.FirstName,person.LastName));


namespace SimpleTemplate;
[TemplateProperty("Hello", "Hello {name1}, {name2}!")]
internal partial class Person
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
}


   The code that is generated is

global using JKToolKit.TemplatePropertyGenerator.Attributes;

using System;

namespace JKToolKit.TemplatePropertyGenerator.Attributes;

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
internal class TemplatePropertyAttribute : Attribute
{
    public string Name { get; }
    public string Format { get; }

    public TemplatePropertyAttribute(string name, string format)
    {
        Name = name;
        Format = format;
    }
}
// <auto-generated>
using System;
namespace SimpleTemplate
{
    internal partial class Person
    {
        public static readonly HelloClass Hello = new();

        public class HelloClass
        {
            public string Template =&gt; "Hello {name1}, {name2}!";

            internal HelloClass()
            {
            }

            public string Format(string name1, string name2)
            {
                return $"Hello {name1}, {name2}!";
            }

            public FormattableString AsFormattable(string name1, string name2)
            {
                return $"Hello {name1}, {name2}!";
            }
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/JKToolKit.TemplatePropertyGenerator

RSCG – DotnetYang

RSCG – DotnetYang    

name DotnetYang
nuget https://www.nuget.org/packages/DotnetYang/
link https://github.com/westermo/DotnetYang
author Westermo Network Technologies

Generating source code from YANG models

  

This is how you can use DotnetYang .

The code that you start with is


<project sdk="Microsoft.NET.Sdk">

  <propertygroup>
    <outputtype>Exe</outputtype>
    <targetframework>net8.0</targetframework>
    <implicitusings>enable</implicitusings>
    <nullable>enable</nullable>
  </propertygroup>

  
  <itemgroup>
    <additionalfiles include="demo.yang">
  </additionalfiles>

	 <propertygroup>
        <emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
        <compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
    </propertygroup>	
  <itemgroup>
    <packagereference version="0.3.0" include="dotnetYang">
  </packagereference>

</itemgroup>


The code that you will use is


Console.WriteLine("Yang file from https://info.support.huawei.com/info-finder/encyclopedia/en/YANG.html#content4!");
Some.Module.YangNode.DoSomethingInput input = new Some.Module.YangNode.DoSomethingInput
{
    TheBigLeaf = 123
};


module some-module {
    yang-version 1.1;
    namespace "urn:dotnet:yang:andrei";
    prefix sm;
    identity someIdentity;
    identity someOtherIdentity
    {
        base someIdentity;
    }
    rpc doSomething {
        input {
            leaf the-big-leaf
            {
                type uint32;
                default "4";
                description "The value that is the input of the doSomething rpc";
            }
        }
        output {
            leaf response
            {
                type identityref
                {
                    base someIdentity;
                }
                default "someOtherIdentity";
                description "The identity that is the output of the doSomething rpc";
            }
        }
    }
}

   The code that is generated is

using System;
using System.Xml;
using YangSupport;
namespace yangDemo;
///<summary>
///Configuration root object for yangDemo based on provided .yang modules
///</summary>

public class Configuration
{
    public Some.Module.YangNode? SomeModule { get; set; }
    public async Task WriteXMLAsync(XmlWriter writer)
	{
	    await writer.WriteStartElementAsync(null,"root",null);
	    
	    if(SomeModule is not null) await SomeModule.WriteXMLAsync(writer);
	    await writer.WriteEndElementAsync();
	}
    public static async Task<configuration> ParseAsync(XmlReader reader)
	{
	    Some.Module.YangNode? _SomeModule = default!;
	    while(await reader.ReadAsync())
	    {
	       switch(reader.NodeType)
	       {
	           case XmlNodeType.Element:
	               switch(reader.Name)
	               {
	                    case "some-module":
						    _SomeModule = await Some.Module.YangNode.ParseAsync(reader);
						    continue;
	                    case "rpc-error": throw await RpcException.ParseAsync(reader);
	                    default: throw new Exception($"Unexpected element '{reader.Name}' under 'root'");
	               }
	           case XmlNodeType.EndElement when reader.Name == "root":
	               return new Configuration{
	                   SomeModule = _SomeModule,
	               };
	           case XmlNodeType.Whitespace: break;
	           default: throw new Exception($"Unexpected node type '{reader.NodeType}' : '{reader.Name}' under 'root'");
	       }
	    }
	    throw new Exception("Reached end-of-readability without ever returning from Configuration.ParseAsync");
	}
}
public static class IYangServerExtensions
{
   public static async Task Receive(this IYangServer server, global::System.IO.Stream input, global::System.IO.Stream output)
   {
       var initialPosition = output.Position;
       var initialLength = output.Length;
       string? id = null;
       using XmlReader reader = XmlReader.Create(input, SerializationHelper.GetStandardReaderSettings());
       using XmlWriter writer = XmlWriter.Create(output, SerializationHelper.GetStandardWriterSettings());
       try
       {
           await reader.ReadAsync();
           switch(reader.Name)
           {
               case "rpc":
                   id = reader.ParseMessageId();
                   await writer.WriteStartElementAsync(null, "rpc-reply", "urn:ietf:params:xml:ns:netconf:base:1.0");
                   await writer.WriteAttributeStringAsync(null, "message-id", null, id);
                   await reader.ReadAsync();
                   switch(reader.Name)
                   {
                       case "action":
                           await server.ReceiveAction(reader, writer);
                           break;
                       default:
                           await server.ReceiveRPC(reader, writer);
                           break;
                   }
                   await writer.WriteEndElementAsync();
                   await writer.FlushAsync();
                   break;
               case "notification":
                   var eventTime = await reader.ParseEventTime();
                   await reader.ReadAsync();
                   await server.ReceiveNotification(reader, eventTime);
                   break;
           }
       }
       catch(RpcException ex)
       {
           await writer.FlushAsync();
           output.Position = initialPosition;
           output.SetLength(initialLength);
           await ex.SerializeAsync(output,id);
       }
       catch(Exception ex)
       {
           await writer.FlushAsync();
           output.Position = initialPosition;
           output.SetLength(initialLength);
           await output.SerializeRegularExceptionAsync(ex,id);
       }
   }
   public static async Task ReceiveRPC(this IYangServer server, XmlReader reader, XmlWriter writer)
   {
       switch(reader.Name)
       {
           case "doSomething" when reader.NamespaceURI is "urn:dotnet:yang:andrei":
			{
			    var input = await Some.Module.YangNode.DoSomethingInput.ParseAsync(reader);
			    var task = server.OnDoSomething(input);
			    var response = await task;
			    await response.WriteXMLAsync(writer);
			}
			break;
       }
   }
   public static async Task ReceiveAction(this IYangServer server, XmlReader reader, XmlWriter writer)
   {
       await reader.ReadAsync();
       switch(reader.Name)
       {
           
       }
   }
   public static async Task ReceiveNotification(this IYangServer server, XmlReader reader, DateTime eventTime)
   {
       switch(reader.Name)
       {
           
           
       }
   }
}
using System;
using System.Xml;
using System.Text;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using YangSupport;
namespace yangDemo
{
    public partial interface IYangServer
    {
        Task<some.module.yangnode.dosomethingoutput> OnDoSomething(Some.Module.YangNode.DoSomethingInput input);
    }
}
namespace Some.Module{
public class YangNode
{
    public const string ModuleName = "some-module";
    public const string Revision = "";
    public static string[] Features = [];
    //Yang Version 1.1
	public const string Namespace = "urn:dotnet:yang:andrei";
	public static string GetEncodedValue(SomeIdentityIdentity value)
	{
	    switch(value)
	    {
	        case SomeIdentityIdentity.SomeIdentity: return "someIdentity";
			case SomeIdentityIdentity.SomeOtherIdentity: return "someOtherIdentity";
	        default: return value.ToString();
	    }
	}
	public static string GetEncodedValue(SomeIdentityIdentity? value) =&gt; GetEncodedValue(value!.Value!);
	public static SomeIdentityIdentity GetSomeIdentityIdentityValue(string value)
	{
	    switch(value)
	    {
	        case "someIdentity": return SomeIdentityIdentity.SomeIdentity;
			case "someOtherIdentity": return SomeIdentityIdentity.SomeOtherIdentity;
	        default: throw new Exception($"{value} is not a valid value for SomeIdentityIdentity");
	    }
	}
	public enum SomeIdentityIdentity
	{
	    SomeIdentity,
		SomeOtherIdentity
	}
	public static string GetEncodedValue(SomeOtherIdentityIdentity value)
	{
	    switch(value)
	    {
	        case SomeOtherIdentityIdentity.SomeOtherIdentity: return "someOtherIdentity";
	        default: return value.ToString();
	    }
	}
	public static string GetEncodedValue(SomeOtherIdentityIdentity? value) =&gt; GetEncodedValue(value!.Value!);
	public static SomeOtherIdentityIdentity GetSomeOtherIdentityIdentityValue(string value)
	{
	    switch(value)
	    {
	        case "someOtherIdentity": return SomeOtherIdentityIdentity.SomeOtherIdentity;
	        default: throw new Exception($"{value} is not a valid value for SomeOtherIdentityIdentity");
	    }
	}
	public enum SomeOtherIdentityIdentity
	{
	    SomeOtherIdentity
	}
	public static async Task<some.module.yangnode.dosomethingoutput> DoSomething(IChannel channel, int messageID, Some.Module.YangNode.DoSomethingInput input)
	{
	    using XmlWriter writer = XmlWriter.Create(channel.WriteStream, SerializationHelper.GetStandardWriterSettings());
	    await writer.WriteStartElementAsync(null,"rpc","urn:ietf:params:xml:ns:netconf:base:1.0");
	    await writer.WriteAttributeStringAsync(null,"message-id",null,messageID.ToString());
	    await writer.WriteStartElementAsync("","doSomething","urn:dotnet:yang:andrei");
		await input.WriteXMLAsync(writer);
	    await writer.WriteEndElementAsync();
	    await writer.WriteEndElementAsync();
	    await writer.FlushAsync();
	    await channel.Send();
	    using XmlReader reader = XmlReader.Create(channel.ReadStream, SerializationHelper.GetStandardReaderSettings());
	    await reader.ReadAsync();
	    if(reader.NodeType != XmlNodeType.Element || reader.Name != "rpc-reply" || reader.NamespaceURI != "urn:ietf:params:xml:ns:netconf:base:1.0" || reader["message-id"] != messageID.ToString())
	    {
	        throw new Exception($"Expected stream to start with a <rpc-reply> element with message id {messageID} &amp; \"urn:ietf:params:xml:ns:netconf:base:1.0\" but got {reader.NodeType}: {reader.Name} in {reader.NamespaceURI}");
	    }
		var value = await DoSomethingOutput.ParseAsync(reader);
	    return value;
	}
	public class DoSomethingOutput
	{
	    ///<summary>
		///The identity that is the output of the doSomething rpc
		///</summary>
		public SomeIdentityIdentity? Response { get; set; } = SomeIdentityIdentity.SomeOtherIdentity;
	    public static async Task<dosomethingoutput> ParseAsync(XmlReader reader)
	{
	    SomeIdentityIdentity? _Response = default!;
	    while(await reader.ReadAsync())
	    {
	       switch(reader.NodeType)
	       {
	           case XmlNodeType.Element:
	               switch(reader.Name)
	               {
	                    case "response":
						    await reader.ReadAsync();
							if(reader.NodeType != XmlNodeType.Text)
							{
							    throw new Exception($"Expected token in ParseCall for 'response' to be text, but was '{reader.NodeType}'");
							}
							_Response = GetSomeIdentityIdentityValue(await reader.GetValueAsync());
							if(!reader.IsEmptyElement)
							{
							    await reader.ReadAsync();
							    if(reader.NodeType != XmlNodeType.EndElement)
							    {
							        throw new Exception($"Expected token in ParseCall for 'response' to be an element closure, but was '{reader.NodeType}'");
							    }
							}
						    continue;
	                    case "rpc-error": throw await RpcException.ParseAsync(reader);
	                    default: throw new Exception($"Unexpected element '{reader.Name}' under 'rpc-reply'");
	               }
	           case XmlNodeType.EndElement when reader.Name == "rpc-reply":
	               return new DoSomethingOutput{
	                   Response = _Response,
	               };
	           case XmlNodeType.Whitespace: break;
	           default: throw new Exception($"Unexpected node type '{reader.NodeType}' : '{reader.Name}' under 'rpc-reply'");
	       }
	    }
	    throw new Exception("Reached end-of-readability without ever returning from DoSomethingOutput.ParseAsync");
	}
	    public async Task WriteXMLAsync(XmlWriter writer)
	{
	    if(Response != default)
		{
		    await writer.WriteStartElementAsync(null,"response","urn:dotnet:yang:andrei");
		    await writer.WriteStringAsync(YangNode.GetEncodedValue(Response!));
		    await writer.WriteEndElementAsync();
		}
	}
	}
	public class DoSomethingInput
	{
	    ///<summary>
		///The value that is the input of the doSomething rpc
		///</summary>
		public uint? TheBigLeaf { get; set; } = 4;
	    public async Task WriteXMLAsync(XmlWriter writer)
		{
		    if(TheBigLeaf != default)
			{
			    await writer.WriteStartElementAsync(null,"the-big-leaf","urn:dotnet:yang:andrei");
			    await writer.WriteStringAsync(TheBigLeaf!.ToString());
			    await writer.WriteEndElementAsync();
			}
		}
	    public static async Task<dosomethinginput> ParseAsync(XmlReader reader)
		{
		    uint? _TheBigLeaf = default!;
		    while(await reader.ReadAsync())
		    {
		       switch(reader.NodeType)
		       {
		           case XmlNodeType.Element:
		               switch(reader.Name)
		               {
		                    case "the-big-leaf":
							    await reader.ReadAsync();
								if(reader.NodeType != XmlNodeType.Text)
								{
								    throw new Exception($"Expected token in ParseCall for 'the-big-leaf' to be text, but was '{reader.NodeType}'");
								}
								_TheBigLeaf = uint.Parse(await reader.GetValueAsync());
								if(!reader.IsEmptyElement)
								{
								    await reader.ReadAsync();
								    if(reader.NodeType != XmlNodeType.EndElement)
								    {
								        throw new Exception($"Expected token in ParseCall for 'the-big-leaf' to be an element closure, but was '{reader.NodeType}'");
								    }
								}
							    continue;
		                    case "rpc-error": throw await RpcException.ParseAsync(reader);
		                    default: throw new Exception($"Unexpected element '{reader.Name}' under 'doSomething'");
		               }
		           case XmlNodeType.EndElement when reader.Name == "doSomething":
		               return new DoSomethingInput{
		                   TheBigLeaf = _TheBigLeaf,
		               };
		           case XmlNodeType.Whitespace: break;
		           default: throw new Exception($"Unexpected node type '{reader.NodeType}' : '{reader.Name}' under 'doSomething'");
		       }
		    }
		    throw new Exception("Reached end-of-readability without ever returning from DoSomethingInput.ParseAsync");
		}
	}
    public static async Task<some.module.yangnode> ParseAsync(XmlReader reader)
	{
	    while(await reader.ReadAsync())
	    {
	       switch(reader.NodeType)
	       {
	           case XmlNodeType.Element:
	               switch(reader.Name)
	               {
	                    case "rpc-error": throw await RpcException.ParseAsync(reader);
	                    default: throw new Exception($"Unexpected element '{reader.Name}' under 'some-module'");
	               }
	           case XmlNodeType.EndElement when reader.Name == "some-module":
	               return new Some.Module.YangNode{
	               };
	           case XmlNodeType.Whitespace: break;
	           default: throw new Exception($"Unexpected node type '{reader.NodeType}' : '{reader.Name}' under 'some-module'");
	       }
	    }
	    throw new Exception("Reached end-of-readability without ever returning from Some.Module.YangNode.ParseAsync");
	}
    public async Task WriteXMLAsync(XmlWriter writer)
	{
	    await writer.WriteStartElementAsync(null,"some-module","urn:dotnet:yang:andrei");
	    await writer.WriteEndElementAsync();
	}
}
}

Code and pdf at

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

RSCG – depso

RSCG – depso    

name depso
nuget https://www.nuget.org/packages/depso/
link https://github.com/notanaverageman/Depso
author Yusuf Tarık Günaydın

generating DI code

  

This is how you can use depso .

The code that you start with is


<project sdk="Microsoft.NET.Sdk">

  <propertygroup>
    <outputtype>Exe</outputtype>
    <targetframework>net8.0</targetframework>
    <implicitusings>enable</implicitusings>
    <nullable>enable</nullable>
  </propertygroup>
	<itemgroup>
		<packagereference version="1.0.1" include="Depso">
	</packagereference>
	<propertygroup>
		<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
		<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
	</propertygroup>
</itemgroup>


The code that you will use is


using InjectDemo;
MyServiceProvider sc = new();
var con = sc.GetService(typeof(Database)) as IDatabase;
ArgumentNullException.ThrowIfNull(con);
con.Open();


[Depso.ServiceProvider]
public partial class MyServiceProvider
{
    private void RegisterServices()
    {
        AddTransient<database database="" ,="">();
        AddTransient<idatabase databasecon="" ,="">();
    }
}


namespace InjectDemo;

partial class Database : IDatabase
{
    private readonly IDatabase con;

    public Database(IDatabase con)
    {
        this.con = con;
    }
    public void Open()
    {
        Console.WriteLine($"open from database");
        con.Open();
    }

}





namespace InjectDemo;

public partial class DatabaseCon:IDatabase
{
    public string? Connection { get; set; }
    public void Open()
    {
        Console.WriteLine("open from database con" );
    }
}



   The code that is generated is

// <auto-generated>

#nullable enable

namespace Depso
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Class)]
    internal sealed class ServiceProviderAttribute : global::System.Attribute
    {
    }
}
// <auto-generated>

#nullable enable

namespace Depso
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Class)]
    internal sealed class ServiceProviderModuleAttribute : global::System.Attribute
    {
    }
}
// <auto-generated>

#nullable enable

public partial class MyServiceProvider
    :
    global::System.IDisposable,
    global::System.IAsyncDisposable,
    global::System.IServiceProvider
{
    private readonly object _sync = new object();

    private global::MyServiceProvider.Scope? _rootScope;
    private global::MyServiceProvider.Scope RootScope =&gt; _rootScope ??= CreateScope(_sync);

    private bool _isDisposed;

    public object? GetService(global::System.Type serviceType)
    {
        if (serviceType == typeof(global::InjectDemo.Database)) return CreateDatabase_0();
        if (serviceType == typeof(global::InjectDemo.IDatabase)) return CreateDatabaseCon_0();
        if (serviceType == typeof(global::System.IServiceProvider)) return this;

        return null;
    }

    private T GetService<t>()
    {
        return (T)GetService(typeof(T))!;
    }

    private global::InjectDemo.Database CreateDatabase_0()
    {
        return new global::InjectDemo.Database(GetService<global::injectdemo.idatabase>());
    }

    private global::InjectDemo.DatabaseCon CreateDatabaseCon_0()
    {
        return new global::InjectDemo.DatabaseCon();
    }

    private global::MyServiceProvider.Scope CreateScope(object? sync)
    {
        ThrowIfDisposed();
        return new global::MyServiceProvider.Scope(this, sync);
    }

    public void Dispose()
    {
        lock (_sync)
        {
            if (_isDisposed)
            {
                return;
            }

            _isDisposed = true;
        }

        if (_rootScope != null) _rootScope.Dispose();
    }

    public async global::System.Threading.Tasks.ValueTask DisposeAsync()
    {
        lock (_sync)
        {
            if (_isDisposed)
            {
                return;
            }

            _isDisposed = true;
        }

        if (_rootScope != null) await _rootScope.DisposeAsync();
    }

    private void ThrowIfDisposed()
    {
        if (_isDisposed)
        {
            throw new global::System.ObjectDisposedException("MyServiceProvider");
        }
    }
}

// <auto-generated>

#nullable enable

public partial class MyServiceProvider
{
    private class RegistrationModifier
    {
        public static readonly global::MyServiceProvider.RegistrationModifier Instance;

        static RegistrationModifier()
        {
            Instance = new global::MyServiceProvider.RegistrationModifier();
        }

        private RegistrationModifier()
        {
        }

        public global::MyServiceProvider.RegistrationModifier AlsoAsSelf()
        {
            return this;
        }

        public global::MyServiceProvider.RegistrationModifier AlsoAs(global::System.Type type)
        {
            return this;
        }

        public global::MyServiceProvider.RegistrationModifier AlsoAs<t>()
        {
            return this;
        }
    }

    private global::MyServiceProvider.RegistrationModifier ImportModule<t>()
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier ImportModule(global::System.Type moduleType)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddSingleton(global::System.Type serviceType)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddSingleton(global::System.Type serviceType, global::System.Type implementationType)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddSingleton<tservice>()
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddSingleton<tservice timplementation="" ,="">() where TImplementation : TService
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddSingleton<tservice>(global::System.Func<global::system.iserviceprovider tservice="" ,=""> factory)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddScoped(global::System.Type serviceType)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddScoped(global::System.Type serviceType, global::System.Type implementationType)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddScoped<tservice>()
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddScoped<tservice timplementation="" ,="">() where TImplementation : TService
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddScoped<tservice>(global::System.Func<global::system.iserviceprovider tservice="" ,=""> factory)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddTransient(global::System.Type serviceType)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddTransient(global::System.Type serviceType, global::System.Type implementationType)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddTransient<tservice>()
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddTransient<tservice timplementation="" ,="">() where TImplementation : TService
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }

    private global::MyServiceProvider.RegistrationModifier AddTransient<tservice>(global::System.Func<global::system.iserviceprovider tservice="" ,=""> factory)
    {
        return global::MyServiceProvider.RegistrationModifier.Instance;
    }
}

// <auto-generated>

#nullable enable

public partial class MyServiceProvider
{
    public class Scope
        :
        global::System.IDisposable,
        global::System.IAsyncDisposable,
        global::System.IServiceProvider
    {
        private readonly object _sync = new object();
        private readonly global::MyServiceProvider _root;

        private bool _isDisposed;

        public Scope(global::MyServiceProvider root, object? sync)
        {
            _root = root;

            if (sync != null)
            {
                _sync = sync;
            }
        }

        public object? GetService(global::System.Type serviceType)
        {
            if (serviceType == typeof(global::InjectDemo.Database)) return _root.CreateDatabase_0();
            if (serviceType == typeof(global::InjectDemo.IDatabase)) return _root.CreateDatabaseCon_0();
            if (serviceType == typeof(global::System.IServiceProvider)) return this;

            return null;
        }

        private T GetService<t>()
        {
            return (T)GetService(typeof(T))!;
        }

        public void Dispose()
        {
            lock (_sync)
            {
                if (_isDisposed)
                {
                    return;
                }

                _isDisposed = true;
            }
        }

        public global::System.Threading.Tasks.ValueTask DisposeAsync()
        {
            lock (_sync)
            {
                if (_isDisposed)
                {
                    return default;
                }

                _isDisposed = true;
            }

            return default;
        }

        private void ThrowIfDisposed()
        {
            if (_isDisposed)
            {
                throw new global::System.ObjectDisposedException("MyServiceProvider.Scope");
            }
        }
    }
}

Code and pdf at

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

RSCG – FactoryGenerator

RSCG – FactoryGenerator    

name FactoryGenerator
nuget https://www.nuget.org/packages/FactoryGenerator/
link https://github.com/westermo/FactoryGenerator
author Westermo Network Technologies

generating DI code

  

This is how you can use FactoryGenerator .

The code that you start with is


<project sdk="Microsoft.NET.Sdk">

  <propertygroup>
    <outputtype>Exe</outputtype>
    <targetframework>net8.0</targetframework>
    <implicitusings>enable</implicitusings>
    <nullable>enable</nullable>
  </propertygroup>
	<propertygroup>
		<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
		<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
	</propertygroup>
	<itemgroup>
	  <packagereference version="1.0.11" include="FactoryGenerator">
	  <packagereference version="1.0.11" include="FactoryGenerator.Attributes">
	</packagereference>
</packagereference>


The code that you will use is


using InjectDemo;

InjectDemo.Generated.DependencyInjectionContainer sc = new();
var db = sc.Resolve<idatabase>();
db.Open();




using FactoryGenerator.Attributes;

namespace InjectDemo;

[Inject, Scoped]
public partial class Database : IDatabase
{
    private readonly DatabaseCon con;

    public Database(DatabaseCon con)
    {
        this.con = con;
    }
    public void Open()
    {
        Console.WriteLine($"open {con.Connection}");
        this.con.Open();
    }

}





using FactoryGenerator.Attributes;

namespace InjectDemo;

[Inject,Scoped, Self]
public partial class DatabaseCon: IDatabase
{
    public string? Connection { get; set; }
    public void Open()
    {
        Console.WriteLine("open" + Connection);
    }
}



   The code that is generated is


using System;
using System.Collections.Generic;
using FactoryGenerator;
using System.CodeDom.Compiler;
namespace InjectDemo.Generated;
#nullable enable
public partial class DependencyInjectionContainer
{
    
    public DependencyInjectionContainer()
    {
        
        
        m_lookup = new(2)
        {
			{ typeof(InjectDemo.IDatabase),InjectDemo_IDatabase },
			{ typeof(InjectDemo.DatabaseCon),InjectDemo_DatabaseCon },




        };
    }

    
public ILifetimeScope BeginLifetimeScope()
{
    var scope = new LifetimeScope(this);
    resolvedInstances.Add(new WeakReference<idisposable>(scope));
    return scope;
}

}

using System;
using System.Collections.Generic;
using FactoryGenerator;
using System.CodeDom.Compiler;
namespace InjectDemo.Generated;
#nullable enable
public partial class DependencyInjectionContainer
{
    
    internal InjectDemo.DatabaseCon InjectDemo_DatabaseCon()
    {
        if (m_InjectDemo_DatabaseCon != null)
            return m_InjectDemo_DatabaseCon;
    
        lock (m_lock)
        {
            if (m_InjectDemo_DatabaseCon != null)
                return m_InjectDemo_DatabaseCon;
            return m_InjectDemo_DatabaseCon = new InjectDemo.DatabaseCon();
        }
    } 
    internal InjectDemo.DatabaseCon? m_InjectDemo_DatabaseCon;
	
    internal InjectDemo.Database InjectDemo_Database()
    {
        if (m_InjectDemo_Database != null)
            return m_InjectDemo_Database;
    
        lock (m_lock)
        {
            if (m_InjectDemo_Database != null)
                return m_InjectDemo_Database;
            return m_InjectDemo_Database = new InjectDemo.Database(InjectDemo_DatabaseCon());
        }
    } 
    internal InjectDemo.Database? m_InjectDemo_Database;
	internal InjectDemo.IDatabase InjectDemo_IDatabase() =&gt; InjectDemo_Database();
}

using System;
using System.Collections.Generic;
using FactoryGenerator;
using System.CodeDom.Compiler;
namespace InjectDemo.Generated;
#nullable enable
public partial class DependencyInjectionContainer
{
    
}

using System;
using System.Collections.Generic;
using FactoryGenerator;
using System.CodeDom.Compiler;
namespace InjectDemo.Generated;
#nullable enable
[GeneratedCode("FactoryGenerator", "1.0.0")]
#nullable disable
public sealed partial class DependencyInjectionContainer : IContainer
{
    private object m_lock = new();
    private Dictionary<type  ,func><object>> m_lookup;     private readonly List<WeakReference<IDisposable>> resolvedInstances = new();      public T Resolve<T>()     {         return (T)Resolve(typeof(T));     }      public object Resolve(Type type)     {         var instance = m_lookup[type]();         return instance;     }      public void Dispose()     {         foreach (var weakReference in resolvedInstances)         {             if(weakReference.TryGetTarget(out var disposable))             {                 disposable.Dispose();             }         }         resolvedInstances.Clear();     }      public bool TryResolve(Type type, out object resolved)     {         if(m_lookup.TryGetValue(type, out var factory))         {             resolved = factory();             return true;         }         resolved = default;         return false;     }       public bool TryResolve<T>(out T resolved)     {         if(m_lookup.TryGetValue(typeof(T), out var factory))         {             var value = factory();             if(value is T t)             {                 resolved = t;                 return true;             }         }         resolved = default;         return false;     }     public bool IsRegistered(Type type)     {         return m_lookup.ContainsKey(type);     }     public bool IsRegistered<T>() => IsRegistered(typeof(T)); } 
  using System; using System.Collections.Generic; using FactoryGenerator; using System.CodeDom.Compiler; namespace InjectDemo.Generated; #nullable enable public partial class LifetimeScope {          public LifetimeScope(DependencyInjectionContainer fallback)     {         m_fallback = fallback;                  m_lookup = new(2)         { 			{ typeof(InjectDemo.IDatabase),InjectDemo_IDatabase }, 			{ typeof(InjectDemo.DatabaseCon),InjectDemo_DatabaseCon },             };     }        } 
  using System; using System.Collections.Generic; using FactoryGenerator; using System.CodeDom.Compiler; namespace InjectDemo.Generated; #nullable enable public partial class LifetimeScope {          internal InjectDemo.DatabaseCon InjectDemo_DatabaseCon()     {         if (m_InjectDemo_DatabaseCon != null)             return m_InjectDemo_DatabaseCon;              lock (m_lock)         {             if (m_InjectDemo_DatabaseCon != null)                 return m_InjectDemo_DatabaseCon;             return m_InjectDemo_DatabaseCon = new InjectDemo.DatabaseCon();         }     }      internal InjectDemo.DatabaseCon? m_InjectDemo_DatabaseCon; 	     internal InjectDemo.Database InjectDemo_Database()     {         if (m_InjectDemo_Database != null)             return m_InjectDemo_Database;              lock (m_lock)         {             if (m_InjectDemo_Database != null)                 return m_InjectDemo_Database;             return m_InjectDemo_Database = new InjectDemo.Database(InjectDemo_DatabaseCon());         }     }      internal InjectDemo.Database? m_InjectDemo_Database; 	internal InjectDemo.IDatabase InjectDemo_IDatabase() => InjectDemo_Database(); } 
  using System; using System.Collections.Generic; using FactoryGenerator; using System.CodeDom.Compiler; namespace InjectDemo.Generated; #nullable enable public partial class LifetimeScope {      } 
  using System; using System.Collections.Generic; using FactoryGenerator; using System.CodeDom.Compiler; namespace InjectDemo.Generated; #nullable enable [GeneratedCode("FactoryGenerator", "1.0.0")] #nullable disable public sealed partial class LifetimeScope : IContainer {     public ILifetimeScope BeginLifetimeScope()     {         var scope = m_fallback.BeginLifetimeScope();         resolvedInstances.Add(new WeakReference<IDisposable>(scope));         return scope;     }     private object m_lock = new();     private DependencyInjectionContainer m_fallback;     private Dictionary<Type,Func<object>> m_lookup;     private readonly List<WeakReference<IDisposable>> resolvedInstances = new();     public T Resolve<T>()     {         return (T)Resolve(typeof(T));     }      public object Resolve(Type type)     {         var instance = m_lookup[type]();         return instance;     }      public void Dispose()     {         foreach (var weakReference in resolvedInstances)         {             if(weakReference.TryGetTarget(out var disposable))             {                 disposable.Dispose();             }         }         resolvedInstances.Clear();     }      public bool TryResolve(Type type, out object resolved)     {         if(m_lookup.TryGetValue(type, out var factory))         {             resolved = factory();             return true;         }         resolved = default;         return false;     }       public bool TryResolve<T>(out T resolved)     {         if(m_lookup.TryGetValue(typeof(T), out var factory))         {             var value = factory();             if(value is T t)             {                 resolved = t;                 return true;             }         }         resolved = default;         return false;     }     public bool IsRegistered(Type type)     {         return m_lookup.ContainsKey(type);     }     public bool IsRegistered<T>() => IsRegistered(typeof(T)); }  

Code and pdf at https://ignatandrei.github.io/RSCG_Examples/v2/docs/FactoryGenerator

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.