Skip to content

Commit 7e6b3a1

Browse files
Sometimes value overrides are performed on undefined variables
1 parent ab8dcc4 commit 7e6b3a1

12 files changed

Lines changed: 331 additions & 15 deletions

File tree

src/Pure.DI.Core/Core/ApiInvocationProcessor.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,9 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
174174
ImmutableArray<MdTagAttribute>.Empty,
175175
ImmutableArray<MdOrdinalAttribute>.Empty,
176176
ImmutableArray<MdAccumulator>.Empty,
177-
Array.Empty<MdTagOnSites>(),
178-
comments.FilterHints(invocationComments).ToList()));
177+
[],
178+
comments.FilterHints(invocationComments).ToList(),
179+
null));
179180
break;
180181

181182
case nameof(IConfiguration.DefaultLifetime):

src/Pure.DI.Core/Core/Code/CompositionBuilder.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ sealed class CompositionBuilder(
1212
ICodeBuilder<IStatement> statementBuilder,
1313
IBuilder<CompositionCode, LinesBuilder> classDiagramBuilder,
1414
Func<IVariablesMap> variablesMapFactory,
15+
IVariableNameProvider variableNameProvider,
1516
CancellationToken cancellationToken)
1617
: IBuilder<DependencyGraph, CompositionCode>
1718
{
@@ -48,9 +49,13 @@ public CompositionCode Build(DependencyGraph graph)
4849
}
4950
}
5051

51-
foreach (var overrideVar in map.GetOverrides())
52+
if (graph.Source.Overrides is {} overrides)
5253
{
53-
ctx.Code.AppendLine($"{typeResolver.Resolve(graph.Source, overrideVar.InstanceType)} {overrideVar.VariableName};");
54+
foreach (var @override in overrides.GetOverrides(root.Node))
55+
{
56+
var variableName = variableNameProvider.GetOverrideVariableName(@override.Source);
57+
ctx.Code.AppendLine($"{typeResolver.Resolve(graph.Source, @override.Source.ContractType)} {variableName};");
58+
}
5459
}
5560

5661
blockBuilder.Build(ctx, rootBlock);

src/Pure.DI.Core/Core/Code/IVariablesMap.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,4 @@ interface IVariablesMap : IDictionary<MdBinding, Variable>
99
IEnumerable<Variable> GetSingletons();
1010

1111
IEnumerable<Variable> GetPerResolves();
12-
13-
IEnumerable<Variable> GetOverrides();
1412
}

src/Pure.DI.Core/Core/Code/VariablesMap.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,4 @@ public IEnumerable<Variable> GetSingletons() => this
3030
public IEnumerable<Variable> GetPerResolves() => this
3131
.Where(i => i.Key.Lifetime?.Value == Lifetime.PerResolve && i.Key.Construct is not { Kind: MdConstructKind.Override })
3232
.Select(i => i.Value);
33-
34-
public IEnumerable<Variable> GetOverrides() => this
35-
.Where(i => i.Key.Construct is { Kind: MdConstructKind.Override })
36-
.Select(i => i.Value);
3733
}

src/Pure.DI.Core/Core/GraphOverrider.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public IGraph<DependencyNode, Dependency> Rewrite(
1717
var nodesMap = new Dictionary<Injection, DependencyNode>();
1818
foreach (var rootNode in from node in graph.Vertices where node.Root is not null select node)
1919
{
20-
Override(processedNodes, [], nodesMap, [], setup, graph, rootNode, ref maxId, entries);
20+
Override(processedNodes, [], nodesMap, [], setup, graph, rootNode, rootNode, ref maxId, entries);
2121
if (cancellationToken.IsCancellationRequested)
2222
{
2323
return graph;
@@ -46,6 +46,7 @@ private DependencyNode Override(
4646
Dictionary<int, DpOverride> overridesMap,
4747
MdSetup setup,
4848
IGraph<DependencyNode, Dependency> graph,
49+
DependencyNode rootNode,
4950
DependencyNode targetNode,
5051
ref int maxId,
5152
List<GraphEntry<DependencyNode, Dependency>> entries)
@@ -83,6 +84,11 @@ private DependencyNode Override(
8384
return targetNode;
8485
}
8586

87+
if (targetNode.Root is not null)
88+
{
89+
rootNode = dependency.Source;
90+
}
91+
8692
if (dependency.Position.HasValue)
8793
{
8894
while (lastDependencyPosition < dependency.Position && overridesEnumerator.MoveNext())
@@ -102,6 +108,7 @@ private DependencyNode Override(
102108
@override.Source with { Id = overrideId, ContractType = contractType },
103109
@override.Injections.Select(i => i with { Type = typeConstructor.Construct(setup, i.Type) }).ToImmutableArray());
104110

111+
setup.Overrides?.Register(rootNode, currentOverride);
105112
overridesMap[@override.Source.Id] = currentOverride;
106113
MdBinding? overrideBinding = null;
107114
foreach (var injection in currentOverride.Injections)
@@ -141,7 +148,7 @@ private DependencyNode Override(
141148
if (!overriddenInjections.Contains(currentDependency.Injection)
142149
|| !nodesMap.TryGetValue(currentDependency.Injection, out var overridingSourceNode))
143150
{
144-
var source = Override(processedNodes, overriddenInjections, nodesMap, overridesMap, setup, graph, currentDependency.Source, ref maxId, entries);
151+
var source = Override(processedNodes, overriddenInjections, nodesMap, overridesMap, setup, graph, rootNode, currentDependency.Source, ref maxId, entries);
145152
currentDependency = currentDependency with { Source = source };
146153
}
147154
else
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Pure.DI.Core;
2+
3+
interface IOverridesRegistry
4+
{
5+
void Register(DependencyNode rootNode, DpOverride @override);
6+
7+
IEnumerable<DpOverride> GetOverrides(DependencyNode rootNode);
8+
}

src/Pure.DI.Core/Core/MetadataBuilder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ sealed class MetadataBuilder(
1313
Func<IBuilder<SyntaxUpdate, IEnumerable<MdSetup>>> setupsBuilderFactory,
1414
Func<ISetupFinalizer> setupFinalizerFactory,
1515
ICompilations compilations,
16+
Func<IOverridesRegistry> overridesFactory,
1617
CancellationToken cancellationToken)
1718
: IBuilder<IEnumerable<SyntaxUpdate>, IEnumerable<MdSetup>>
1819
{
@@ -187,6 +188,7 @@ private void MergeSetups(IEnumerable<MdSetup> setups, out MdSetup mergedSetup, b
187188
ordinalAttributesBuilder.ToImmutable(),
188189
accumulators.ToImmutable(),
189190
tagOn,
190-
comments);
191+
comments,
192+
overridesFactory());
191193
}
192194
}

src/Pure.DI.Core/Core/Models/MdSetup.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ record MdSetup(
2121
in ImmutableArray<MdOrdinalAttribute> OrdinalAttributes,
2222
in ImmutableArray<MdAccumulator> Accumulators,
2323
IReadOnlyCollection<MdTagOnSites> TagOn,
24-
IReadOnlyCollection<string> Comments)
24+
IReadOnlyCollection<string> Comments,
25+
IOverridesRegistry? Overrides)
2526
{
2627
public virtual bool Equals(MdSetup? other) =>
2728
other is not null && (ReferenceEquals(this, other) || Name.Equals(other.Name));
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace Pure.DI.Core;
2+
3+
using System.Collections.Concurrent;
4+
5+
class OverridesRegistry : IOverridesRegistry
6+
{
7+
private readonly ConcurrentDictionary<int, List<DpOverride>> _overrides = new();
8+
9+
public void Register(DependencyNode rootNode, DpOverride @override) =>
10+
_overrides.AddOrUpdate(rootNode.Binding.Id, _ => [@override], (_, list) => {
11+
list.Add(@override);
12+
return list;
13+
});
14+
15+
public IEnumerable<DpOverride> GetOverrides(DependencyNode rootNode) =>
16+
_overrides.TryGetValue(rootNode.Binding.Id, out var overrides)
17+
? overrides.GroupBy(i => i.Source.Id).Select(i => i.First()).ToList()
18+
: [];
19+
}

src/Pure.DI.Core/Generator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ private void Setup() => DI.Setup()
7171
.Bind<IDependencyGraphLocationsWalker>().To<DependencyGraphLocationsWalker>()
7272
.Bind<IFactoryValidator>().To<FactoryValidator>()
7373
.Bind<ILocalVariableRenamingRewriter>().To<LocalVariableRenamingRewriter>()
74+
.Bind().To<OverridesRegistry>()
7475

7576
.DefaultLifetime(Singleton)
7677
.Bind().To<Cache<TT1, TT2>>()

0 commit comments

Comments
 (0)