Skip to content

Commit

Permalink
Booleans now propogate across chains
Browse files Browse the repository at this point in the history
  • Loading branch information
Iacentis committed Sep 11, 2024
1 parent 2889a37 commit 5e4bfbd
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
1 change: 1 addition & 0 deletions FactoryGenerator.Attributes/IContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface ILifetimeScope : IDisposable

bool IsRegistered(Type type);
bool IsRegistered<T>();
bool GetBoolean(string key);
public ILifetimeScope BeginLifetimeScope();
}

Expand Down
26 changes: 23 additions & 3 deletions FactoryGenerator/FactoryGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ private IContainer GetTop()
public IContainer? Inheritor {{ get; set; }}
private object m_lock = new();
private Dictionary<Type,Func<object>> m_lookup;
private Dictionary<string,bool> m_booleans;
private readonly List<WeakReference<IDisposable>> resolvedInstances = new();
public T Resolve<T>()
Expand Down Expand Up @@ -245,6 +246,10 @@ public bool IsRegistered(Type type)
return m_lookup.ContainsKey(type) ? true : Base?.IsRegistered(type) == true;
}}
public bool IsRegistered<T>() => IsRegistered(typeof(T));
public bool GetBoolean(string key)
{{
return m_booleans.TryGetValue(key, out var value) ? value : false;
}}
}}";

var booleans = dataInjections.Select(inj => inj.BooleanInjection).Where(b => b is not null)
Expand Down Expand Up @@ -424,7 +429,7 @@ public bool IsRegistered(Type type)
dictSize, interfaceInjectors.Keys,
localizedParameters, requested,
constructorParameters, true, ClassName, lifetimeParameters,
resolvingConstructorAssignments: resolvedConstructorAssignments);
resolvingConstructorAssignments: resolvedConstructorAssignments, booleans: justBooleans);
yield return Declarations(usingStatements, declarations, ClassName);
yield return ArrayDeclarations(usingStatements, arrayDeclarations, ClassName);
yield return $@"{usingStatements}
Expand Down Expand Up @@ -463,6 +468,7 @@ public ILifetimeScope BeginLifetimeScope()
private object m_lock = new();
private {ClassName} m_fallback;
private Dictionary<Type,Func<object>> m_lookup;
private Dictionary<string,bool> m_booleans;
private readonly List<WeakReference<IDisposable>> resolvedInstances = new();
public T Resolve<T>()
Expand Down Expand Up @@ -527,14 +533,19 @@ public bool IsRegistered(Type type)
return m_lookup.ContainsKey(type) ? true : Base?.IsRegistered(type) == true;
}}
public bool IsRegistered<T>() => IsRegistered(typeof(T));
public bool GetBoolean(string key)
{{
return m_booleans.TryGetValue(key, out var value) ? value : false;
}}
}}
";
yield return Constructor(usingStatements, constructorFields,
lifetimeConstructor, constructorAssignments,
dictSize, interfaceInjectors.Keys,
localizedParameters, requested,
constructorParameters, false, LifetimeName,
resolvingConstructorAssignments: resolvedConstructorAssignments, addMergingConstructor: false);
resolvingConstructorAssignments: resolvedConstructorAssignments, addMergingConstructor: false, booleans: justBooleans);
yield return Declarations(usingStatements, scopedDeclarations, LifetimeName);
yield return ArrayDeclarations(usingStatements, arrayDeclarations, LifetimeName);
}
Expand Down Expand Up @@ -595,7 +606,7 @@ private static void CheckForCycles(ImmutableArray<Injection> dataInjections)
private static string Constructor(string usingStatements, string constructorFields, string constructor, string constructorAssignments, int dictSize,
IEnumerable<INamedTypeSymbol> interfaceInjectors, List<IParameterSymbol> localizedParameters, List<INamedTypeSymbol> requested,
List<IParameterSymbol> constructorParameters, bool addLifetimeScopeFunction, string className, string? lifetimeParameters = null,
string? fromConstructor = null, string? resolvingConstructorAssignments = null, bool addMergingConstructor = true)
string? fromConstructor = null, string? resolvingConstructorAssignments = null, bool addMergingConstructor = true, List<string> booleans = null!)
{
var lifetimeScopeFunction = addLifetimeScopeFunction
? $@"
Expand All @@ -613,12 +624,17 @@ public ILifetimeScope BeginLifetimeScope()
Base.Inheritor = this;
{resolvingConstructorAssignments}
{string.Join("\n", booleans.Select(b => b.Split(' ').Last()).Select(b => $"\t this.{b} = Base.GetBoolean(\"{b}\");"))}
m_lookup = new({dictSize}) {{
{MakeDictionary(interfaceInjectors)}
{MakeDictionary(localizedParameters)}
{MakeDictionary(requested)}
{MakeDictionary(constructorParameters)}
}};
m_booleans = new({booleans.Count}) {{
{string.Join("\n", booleans.Select(b => b.Split(' ').Last()).Select(b => $"\t\t{{ \"{b}\", {b} }},"))}
}};
}}" : string.Empty;


Expand All @@ -638,6 +654,10 @@ public partial class {className}
{MakeDictionary(requested)}
{MakeDictionary(constructorParameters)}
}};
m_booleans = new({booleans.Count}) {{
{string.Join("\n", booleans.Select(b => b.Split(' ').Last()).Select(b => $"\t\t{{ \"{b}\", {b} }},"))}
}};
}}
{mergingConstructor}
{lifetimeScopeFunction}
Expand Down
18 changes: 18 additions & 0 deletions Tests/FactoryGenerator.Tests/InjectionDetectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,19 @@ public void HierarchicalContainersResolveUsesFallBackIfItCannotFindImplementatio
var newContainer = new DependencyInjectionContainer(new DummyContainer());
newContainer.Resolve<string>().ShouldBe(DummyContainer.DummyText);
}

[Fact]
public void ContainerPropgatesRelevantBooleansCreateItself()
{
var baseContainer = new DependencyInjectionContainer(true, false, new());
baseContainer.GetBoolean("A").ShouldBeFalse();
baseContainer.GetBoolean("TestBool").ShouldBeTrue();

var newContainer = new DependencyInjectionContainer(baseContainer);

newContainer.GetBoolean("A").ShouldBeFalse();
newContainer.GetBoolean("TestBool").ShouldBeTrue();
}
private class DummyContainer : IContainer
{
public const string DummyText = "I am a bit of text";
Expand All @@ -257,6 +270,11 @@ public void Dispose()
{
}

public bool GetBoolean(string key)
{
return false;
}

public bool IsRegistered(System.Type type)
{
return true;
Expand Down

0 comments on commit 5e4bfbd

Please sign in to comment.