Category: roslyn

RSCG – Immediate.Handlers

RSCG – Immediate.Handlers
 
 

name Immediate.Handlers
nuget https://www.nuget.org/packages/Immediate.Handlers/
link https://github.com/immediateplatform/Immediate.Handlers
author Stuart Turner

Generating mediator like handlers

 

This is how you can use Immediate.Handlers .

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>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
    <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Immediate.Handlers" Version="1.6.1" />
        <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />     
    </ItemGroup>
 
</Project>

The code that you will use is

01
02
03
04
05
06
07
08
09
10
11
Console.WriteLine("Hello, World!");
ServiceCollection services = new ();
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>));
services.AddHandlers();
services.AddBehaviors();
IHandler<Ping, Pong> handler = services.BuildServiceProvider().GetRequiredService<IHandler<Ping, Pong>>();
var id = Guid.NewGuid();
var request = new Ping(id);
var pong = await handler.HandleAsync(request, CancellationToken.None);
Console.WriteLine($"Got pong with id {pong.Id}!");
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
using Immediate.Handlers.Shared;
 
public sealed record Ping(Guid Id);// : IRequest<Pong>;
 
public sealed record Pong(Guid Id);
 
 
[Handler]
[Behaviors(
    typeof(LoggingBehavior<,>)
)]
public static partial class PingHandler //: IPipelineAction<Ping, Pong>
{
 
    private static async ValueTask<Pong> HandleAsync(Ping request, CancellationToken token)
    {
        await Task.Delay(1000);
        Console.WriteLine("Returning pong!");
        return new Pong(request.Id);
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
public sealed class LoggingBehavior<TRequest, TResponse>(ILogger<LoggingBehavior<TRequest, TResponse>>? logger)
    : Behavior<TRequest, TResponse>
{
    public override async ValueTask<TResponse> HandleAsync(TRequest request, CancellationToken cancellationToken)
    {
        Console.WriteLine("I am a logging behaviour");
        logger?.LogInformation("LoggingBehavior.Enter");
        var response = await Next(request, cancellationToken);
        logger?.LogInformation("LoggingBehavior.Exit");
        return response;
    }
}
1
2
3
4
5
global using Microsoft.Extensions.DependencyInjection;
global using Immediate.Handlers.Shared;
global using Microsoft.Extensions.Logging;
global using Mediator;
global using Microsoft.Extensions.Logging.Abstractions;

 

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using Microsoft.Extensions.DependencyInjection;
 
#pragma warning disable CS1591
 
partial class PingHandler
{
    public sealed partial class Handler : global::Immediate.Handlers.Shared.IHandler<global::Ping, global::Pong>
    {
        private readonly global::PingHandler.HandleBehavior _handleBehavior;
        private readonly global::LoggingBehavior<global::Ping, global::Pong> _loggingBehavior;
 
        public Handler(
            global::PingHandler.HandleBehavior handleBehavior,
            global::LoggingBehavior<global::Ping, global::Pong> loggingBehavior
        )
        {
            var handlerType = typeof(PingHandler);
 
            _handleBehavior = handleBehavior;
 
            _loggingBehavior = loggingBehavior;
            _loggingBehavior.HandlerType = handlerType;
 
            _loggingBehavior.SetInnerHandler(_handleBehavior);
        }
 
        public async global::System.Threading.Tasks.ValueTask<global::Pong> HandleAsync(
            global::Ping request,
            global::System.Threading.CancellationToken cancellationToken = default
        )
        {
            return await _loggingBehavior
                .HandleAsync(request, cancellationToken)
                .ConfigureAwait(false);
        }
    }
 
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class HandleBehavior : global::Immediate.Handlers.Shared.Behavior<global::Ping, global::Pong>
    {
 
        public HandleBehavior(
        )
        {
        }
 
        public override async global::System.Threading.Tasks.ValueTask<global::Pong> HandleAsync(
            global::Ping request,
            global::System.Threading.CancellationToken cancellationToken
        )
        {
            return await global::PingHandler
                .HandleAsync(
                    request
                    , cancellationToken
                )
                .ConfigureAwait(false);
        }
    }
 
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    public static IServiceCollection AddHandlers(
        IServiceCollection services,
        ServiceLifetime lifetime = ServiceLifetime.Scoped
    )
    {
        services.Add(new(typeof(global::PingHandler.Handler), typeof(global::PingHandler.Handler), lifetime));
        services.Add(new(typeof(global::Immediate.Handlers.Shared.IHandler<global::Ping, global::Pong>), typeof(global::PingHandler.Handler), lifetime));
        services.Add(new(typeof(global::PingHandler.HandleBehavior), typeof(global::PingHandler.HandleBehavior), lifetime));
        return services;
    }
}
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
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
 
#pragma warning disable CS1591
 
namespace Mediator;
 
public static class HandlerServiceCollectionExtensions
{
    public static IServiceCollection AddBehaviors(
        this IServiceCollection services)
    {
        services.TryAddTransient(typeof(global::LoggingBehavior<,>));
         
        return services;
    }
 
    public static IServiceCollection AddHandlers(
        this IServiceCollection services,
        ServiceLifetime lifetime = ServiceLifetime.Scoped
    )
    {
        global::PingHandler.AddHandlers(services, lifetime);
         
        return services;
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Immediate.Handlers

RSCG – Sera.Union

RSCG – Sera.Union
 
 

name Sera.Union
nuget https://www.nuget.org/packages/Sera.Union/
link https://github.com/sera-net/Sera.Union
author Sera

Generate tagged union

 

This is how you can use Sera.Union .

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>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
 
    <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
 
    <ItemGroup>
      <PackageReference Include="Sera.Union" Version="0.7.0" />
    </ItemGroup>
 
</Project>

The code that you will use is

01
02
03
04
05
06
07
08
09
10
11
using UnionTypesDemo;
 
Console.WriteLine("Save or not");
var data = SaveToDatabase.Save(0);
Console.WriteLine(data.IsNotFound);
data = SaveToDatabase.Save(1);
if(data.IsOk)
{
    Console.WriteLine(data.Tag);
    Console.WriteLine(data.Ok);
}

 

The code that is generated is

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// <auto-generated/>
 
#nullable enable
 
using Sera.TaggedUnion;
 
namespace UnionTypesDemo {
 
public partial struct ResultSave
    : global::Sera.TaggedUnion.ITaggedUnion
    , global::System.IEquatable<ResultSave>
    , global::System.IComparable<ResultSave>
#if NET7_0_OR_GREATER
    , global::System.Numerics.IEqualityOperators<ResultSave, ResultSave, bool>
    , global::System.Numerics.IComparisonOperators<ResultSave, ResultSave, bool>
#endif
{
    private __impl_ _impl;
    private ResultSave(__impl_ _impl) { this._impl = _impl; }
 
    public readonly Tags Tag
    {
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        get => this._impl._tag;
    }
 
    public enum Tags : byte
    {
        Ok = 1,
        NotFound = 2,
    }
 
    [global::System.Runtime.CompilerServices.CompilerGenerated]
    private struct __impl_
    {
        public __unmanaged_ _unmanaged_;
        public readonly Tags _tag;
 
        [global::System.Runtime.CompilerServices.CompilerGenerated]
        [global::System.Runtime.InteropServices.StructLayout(global::System.Runtime.InteropServices.LayoutKind.Explicit)]
        internal struct __unmanaged_
        {
            [global::System.Runtime.InteropServices.FieldOffset(0)]
            public int _0;
        }
 
        public __impl_(Tags _tag)
        {
            global::System.Runtime.CompilerServices.Unsafe.SkipInit(out this._unmanaged_);
            this._tag = _tag;
        }
    }
 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static ResultSave MakeOk(int value)
    {
        var _impl = new __impl_(Tags.Ok);
        _impl._unmanaged_._0 = value;
        return new ResultSave(_impl);
    }
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static ResultSave MakeNotFound()
    {
        var _impl = new __impl_(Tags.NotFound);
        return new ResultSave(_impl);
    }
 
    public readonly bool IsOk
    {
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        get => this._impl._tag == Tags.Ok;
    }
    public readonly bool IsNotFound
    {
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        get => this._impl._tag == Tags.NotFound;
    }
 
    public int Ok
    {
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        readonly get => !this.IsOk ? default! : this._impl._unmanaged_._0!;
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        set { if (this.IsOk) { this._impl._unmanaged_._0 = value; } }
    }
 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly bool Equals(ResultSave other) => this.Tag != other.Tag ? false : this.Tag switch
    {
        Tags.Ok => global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(this.Ok, other.Ok),
        _ => true,
    };
 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly override int GetHashCode() => this.Tag switch
    {
        Tags.Ok => global::System.HashCode.Combine(this.Tag, this.Ok),
        _ => global::System.HashCode.Combine(this.Tag),
    };
 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly override bool Equals(object? obj) => obj is ResultSave other && Equals(other);
 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator ==(ResultSave left, ResultSave right) => Equals(left, right);
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator !=(ResultSave left, ResultSave right) => !Equals(left, right);
 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly int CompareTo(ResultSave other) => this.Tag != other.Tag ? global::System.Collections.Generic.Comparer<Tags>.Default.Compare(this.Tag, other.Tag) : this.Tag switch
    {
        Tags.Ok => global::System.Collections.Generic.Comparer<int>.Default.Compare(this.Ok, other.Ok),
        _ => 0,
    };
 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator <(ResultSave left, ResultSave right) => left.CompareTo(right) < 0;
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator >(ResultSave left, ResultSave right) => left.CompareTo(right) > 0;
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator <=(ResultSave left, ResultSave right) => left.CompareTo(right) <= 0;
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator >=(ResultSave left, ResultSave right) => left.CompareTo(right) >= 0;
 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly override string ToString() => this.Tag switch
    {
        Tags.Ok => $"{nameof(ResultSave)}.{nameof(Tags.Ok)} {{ {this.Ok} }}",
        Tags.NotFound => $"{nameof(ResultSave)}.{nameof(Tags.NotFound)}",
        _ => nameof(ResultSave),
    };
}
 
} // namespace UnionTypesDemo

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Sera.Union

RSCG – RSCG_NameGenerator

RSCG – RSCG_NameGenerator
 
 

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

Generating unique names for assemblies

 

This is how you can use RSCG_NameGenerator .

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>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>
 
    <ItemGroup>
        <PackageReference Include="RSCG_NameGenerator" Version="2024.26.8.2002" >
            <OutputItemType>Analyzer</OutputItemType>
            <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
        </PackageReference>
    </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 Generated.TestNameGenerator;
//by just putting here
//you will not deploy the dll when you deploy the project
//name are generated in the code source
Console.WriteLine($"Name:{TheAssemblyInfo.GeneratedName}");
Console.WriteLine($"Nice:{TheAssemblyInfo.GeneratedNameNice}");
Console.WriteLine($"Small:{TheAssemblyInfo.GeneratedNameSmall}");
//if you want to generate a new name every time you run the app
//put in the csproj
//<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
//but the dll will be deployed with the app
//Console.WriteLine(NameGenerator.NameGeneratorData.Generate().UniqueNameLong);

 

The code that is generated is

01
02
03
04
05
06
07
08
09
10
11
12
// <auto-generated/>
namespace Generated.TestNameGenerator
{
    public static class TheAssemblyInfo
    {
        public const string AssemblyName = "TestNameGenerator";
        public const string GeneratedNameNice = "Sir Winston Churchill is feeling private in Naypyidaw";
        public const string GeneratedNameSmall = "private-Sir Winston Churchill";
        public const string GeneratedName = "private-Sir Winston Churchill-Naypyidaw";
         
    }
}

Code and pdf at

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

RSCG – Coplt.Dropping

RSCG – Coplt.Dropping
 
 

name Coplt.Dropping
nuget https://www.nuget.org/packages/Coplt.Dropping/
link https://github.com/2A5F/Coplt.Dropping
author 2A5F

Generating disposable

 

This is how you can use Coplt.Dropping .

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
<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="Coplt.Dropping" Version="0.5.1" OutputItemType="Analyzer" />
        
     </ItemGroup>
 
</Project>

The code that you will use is

1
2
3
4
5
6
7
using IDisposableGeneratorDemo;
using (var db = new DALDB())
{
    Console.WriteLine("before releasing");
}
Console.WriteLine("after releasing");
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
using Coplt.Dropping;
 
namespace IDisposableGeneratorDemo;
 
[Dropping]
partial class DALDB :IDisposable
{
    private ConnectionDB cn;
    private ConnectionDB cn1;
 
    public DALDB()
    {
        cn = new ConnectionDB();
        cn1=new ConnectionDB();
    }
    [Drop]
    public void Drop()
    {
        cn.Dispose();
        cn1.Dispose();
    }
}
1
2
3
4
5
6
7
8
9
namespace IDisposableGeneratorDemo;
 
class ConnectionDB : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("disposing connectiondb");
    }
}

 

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
// <auto-generated/>
 
#nullable enable
 
using Coplt.Dropping;
 
namespace IDisposableGeneratorDemo {
 
internal partial class DALDB : global::System.IDisposable
{
 
    protected virtual void Dispose(bool disposing)
    {
        if (disposing) Drop();
    }
 
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
 
    ~DALDB()
    {
        Dispose(false);
    }
 
}
 
} // namespace IDisposableGeneratorDemo

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Coplt.Dropping

RSCG – Fluentify

RSCG – Fluentify
 
 

name Fluentify
nuget https://www.nuget.org/packages/Fluentify/
link https://github.com/MooVC/fluentify
author Paul Martins

Generate fluent builder

 

This is how you can use Fluentify .

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>net8.0</TargetFramework>
  </PropertyGroup>
 
      <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
 
      <ItemGroup>
        <PackageReference Include="Fluentify" Version="1.1.0">
          <PrivateAssets>all</PrivateAssets>
          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
      </ItemGroup>
 
       
</Project>

The code that you will use is

1
2
3
4
5
6
using Builder;
 
var pOld = new Person();
pOld= pOld.WithFirstName("Andrei").WithLastName("Ignat").WithMiddleName("G");
 
System.Console.WriteLine(pOld.FullName());
01
02
03
04
05
06
07
08
09
10
11
12
13
14
namespace Builder;
[Fluentify.Fluentify]
public partial class Person
{
    public string FirstName { get; init; }
    public string? MiddleName { get; init; }
    public string LastName { get; init; }
 
    public string FullName()
    {
        return FirstName + " " + MiddleName + " "+LastName;
    }
     
}

 

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
#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
#nullable enable
#endif
 
#pragma warning disable CS8625
 
namespace Builder
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Fluentify.Internal;
 
    public static partial class PersonExtensions
    {
        public static global::Builder.Person WithFirstName(
            this global::Builder.Person subject,
            string value)
        {
            subject.ThrowIfNull("subject");
 
            return new global::Builder.Person
            {
                FirstName = value,
                MiddleName = subject.MiddleName,
                LastName = subject.LastName,
            };
        }
    }
}
 
#pragma warning restore CS8625
 
#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
#nullable restore
#endif
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
#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
#nullable enable
#endif
 
#pragma warning disable CS8625
 
namespace Builder
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Fluentify.Internal;
 
    public static partial class PersonExtensions
    {
        public static global::Builder.Person WithLastName(
            this global::Builder.Person subject,
            string value)
        {
            subject.ThrowIfNull("subject");
 
            return new global::Builder.Person
            {
                FirstName = subject.FirstName,
                MiddleName = subject.MiddleName,
                LastName = value,
            };
        }
    }
}
 
#pragma warning restore CS8625
 
#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
#nullable restore
#endif
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
#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
#nullable enable
#endif
 
#pragma warning disable CS8625
 
namespace Builder
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Fluentify.Internal;
 
    public static partial class PersonExtensions
    {
        public static global::Builder.Person WithMiddleName(
            this global::Builder.Person subject,
            string? value)
        {
            subject.ThrowIfNull("subject");
 
            return new global::Builder.Person
            {
                FirstName = subject.FirstName,
                MiddleName = value,
                LastName = subject.LastName,
            };
        }
    }
}
 
#pragma warning restore CS8625
 
#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
#nullable restore
#endif
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
namespace Fluentify
{
    using System;
    using System.Diagnostics.CodeAnalysis;
 
    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    internal sealed class DescriptorAttribute
        : Attribute
    {
        public DescriptorAttribute(string value)
        {
            Value = value;
        }
 
        public string Value { get; }
    }
}
01
02
03
04
05
06
07
08
09
10
namespace Fluentify
{
    using System;
 
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    internal sealed class FluentifyAttribute
        : Attribute
    {
    }
}
01
02
03
04
05
06
07
08
09
10
namespace Fluentify
{
    using System;
 
    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    internal sealed class IgnoreAttribute
        : Attribute
    {
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
namespace Fluentify.Internal
{
    using System;
 
    internal static class Extensions
    {
        public static void ThrowIfNull(this object subject, string paramName)
        {
            if (subject == null)
            {
                throw new ArgumentNullException(paramName);
            }
        }
    }
}

Code and pdf at

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

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

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
<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

01
02
03
04
05
06
07
08
09
10
11
using Person;
 
internal class Program
{
    private static void Main(string[] args)
    {
        PersonData person = new ();
        person.Name = "Andrei Ignat";
        Console.WriteLine(person.Name);
    }
}
1
2
3
4
5
6
7
namespace Person;
 
public class PersonData
{
    public string Name { get; set; }
    public int Age { get; set; }
}

 

The code that is generated is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
//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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
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)
    ;
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
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();
    }
 
}
01
02
03
04
05
06
07
08
09
10
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

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
42
43
44
45
46
47
48
49
50
51
52
#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; }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
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

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
<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

1
Console.WriteLine(ThisAssembly.Strings.PersonName("Andrei Ignat"));
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//------------------------------------------------------------------------------
// <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);
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
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 – 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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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

1
2
3
4
5
Some.Module.YangNode.DoSomethingInput input = new Some.Module.YangNode.DoSomethingInput
{
    TheBigLeaf = 123
};
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
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

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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)
       {
            
            
       }
   }
}
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
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="" ,="">();
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
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();
    }
 
}
01
02
03
04
05
06
07
08
09
10
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

01
02
03
04
05
06
07
08
09
10
11
// <auto-generated>
 
#nullable enable
 
namespace Depso
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Class)]
    internal sealed class ServiceProviderAttribute : global::System.Attribute
    {
    }
}
01
02
03
04
05
06
07
08
09
10
11
// <auto-generated>
 
#nullable enable
 
namespace Depso
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Class)]
    internal sealed class ServiceProviderModuleAttribute : global::System.Attribute
    {
    }
}
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// <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");
        }
    }
}
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// <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;
    }
}
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// <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

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.