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