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() => 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
Leave a Reply