Skip to content

Instantly share code, notes, and snippets.

@mrange
Last active June 22, 2021 05:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrange/ddf7c2e3bd3ba727d3ec9003a46b4503 to your computer and use it in GitHub Desktop.
Save mrange/ddf7c2e3bd3ba727d3ec9003a46b4503 to your computer and use it in GitHub Desktop.
Static inject T4
namespace t4inject
{
partial interface IA
{
}
partial class A : IA
{
partial void OnCreated(CreationContext context);
internal void Created(CreationContext context)
{
OnCreated(context);
}
}
partial interface IB
{
}
partial class B : IB
{
internal IA _a = null;
partial void OnCreated(CreationContext context);
internal void Created(CreationContext context)
{
OnCreated(context);
}
}
partial interface IC
{
}
partial class C : IC
{
internal IA _a = null;
internal IB _b = null;
partial void OnCreated(CreationContext context);
internal void Created(CreationContext context)
{
OnCreated(context);
}
}
partial class CreationContext
{
public IA Service_IA = null;
public IB Service_IB = null;
public IC Service_IC = null;
public CreationContext Clone()
{
var cc = new CreationContext();
cc.Service_IA = Service_IA;
cc.Service_IB = Service_IB;
cc.Service_IC = Service_IC;
return cc;
}
}
static partial class Creator
{
static partial void OnCreate(ref CreationContext context, ref IA v);
public static void GetOrCreate(this CreationContext context, out IA v)
{
if (context.Service_IA is null)
{
var ctx = context;
OnCreate(ref ctx, ref context.Service_IA);
if (context.Service_IA is null)
{
var vv = new A();
context.Service_IA = vv;
vv.Created(context);
}
}
v = context.Service_IA;
}
static partial void OnCreate(ref CreationContext context, ref IB v);
public static void GetOrCreate(this CreationContext context, out IB v)
{
if (context.Service_IB is null)
{
var ctx = context;
OnCreate(ref ctx, ref context.Service_IB);
if (context.Service_IB is null)
{
var vv = new B();
if (vv._a is null) GetOrCreate(ctx, out vv._a);
context.Service_IB = vv;
vv.Created(context);
}
}
v = context.Service_IB;
}
static partial void OnCreate(ref CreationContext context, ref IC v);
public static void GetOrCreate(this CreationContext context, out IC v)
{
if (context.Service_IC is null)
{
var ctx = context;
OnCreate(ref ctx, ref context.Service_IC);
if (context.Service_IC is null)
{
var vv = new C();
if (vv._a is null) GetOrCreate(ctx, out vv._a);
if (vv._b is null) GetOrCreate(ctx, out vv._b);
context.Service_IC = vv;
vv.Created(context);
}
}
v = context.Service_IC;
}
}
}
<#
var model = new []
{
Service("IA", "A"),
Service("IB", "B", ("IA", "_a")),
Service("IC", "C", ("IA", "_a"), ("IB", "_b")),
};
#>
namespace t4inject
{
<# foreach (var m in model) { #>
partial interface <#=m.AbstractName#>
{
}
partial class <#=m.ImplName#> : <#=m.AbstractName#>
{
<# foreach (var d in m.Dependencies) { #>
internal <#=d.AbstractName#> <#=d.Name#> = null;
<# } #>
partial void OnCreated(CreationContext context);
internal void Created(CreationContext context)
{
OnCreated(context);
}
}
<# } #>
partial class CreationContext
{
<# foreach (var m in model) { #>
public <#=m.AbstractName#> Service_<#=m.AbstractName#> = null;
<# } #>
public CreationContext Clone()
{
var cc = new CreationContext();
<# foreach (var m in model) { #>
cc.Service_<#=m.AbstractName#> = Service_<#=m.AbstractName#>;
<# } #>
return cc;
}
}
static partial class Creator
{
<# foreach (var m in model) { #>
static partial void OnCreate(ref CreationContext context, ref <#=m.AbstractName#> v);
public static void GetOrCreate(this CreationContext context, out <#=m.AbstractName#> v)
{
if (context.Service_<#=m.AbstractName#> is null)
{
var ctx = context;
OnCreate(ref ctx, ref context.Service_<#=m.AbstractName#>);
if (context.Service_<#=m.AbstractName#> is null)
{
var vv = new <#=m.ImplName#>();
<# foreach (var d in m.Dependencies) { #>
if (vv.<#=d.Name#> is null) GetOrCreate(ctx, out vv.<#=d.Name#>);
<# } #>
context.Service_<#=m.AbstractName#> = vv;
vv.Created(context);
}
}
v = context.Service_<#=m.AbstractName#>;
}
<# } #>
}
}
<#+
(string AbstractName, string ImplName, (string AbstractName, string Name)[] Dependencies) Service(string abstractName, string implName, params (string AbstractName, string Name)[] deps)
{
return (abstractName ?? "<NoName>", implName ?? "<NoName>", deps);
}
#>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment