Skip to content

Commit 7504808

Browse files
Method/property/field injection may not work when using Singleton/Scoped/PerResolve/PerBlock lifetime
1 parent 248f573 commit 7504808

5 files changed

Lines changed: 43 additions & 23 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public IEnumerable<Line> OnCreated(BuildContext ctx, Variable variable)
6363
{
6464
if (variable.Node.Arg is not null)
6565
{
66-
return Array.Empty<Line>();
66+
return [];
6767
}
6868

6969
var baseTypes = new Lazy<ImmutableHashSet<ISymbol?>>(() =>

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public void Build(BuildContext ctx, in DpImplementation implementation)
3838
visits.Add((VisitFieldAction, field.Ordinal));
3939
continue;
4040

41-
void VisitFieldAction(BuildContext context) => injections.FieldInjection(variable.VariableName, context, field, fieldVariable);
41+
void VisitFieldAction(BuildContext context) => injections.FieldInjection(context.Variable.VariableName, context, field, fieldVariable);
4242
}
4343

4444
foreach (var property in implementation.Properties.Where(i => !i.Property.IsRequired && i.Property.SetMethod?.IsInitOnly != true))
@@ -48,7 +48,7 @@ public void Build(BuildContext ctx, in DpImplementation implementation)
4848
visits.Add((VisitFieldAction, property.Ordinal));
4949
continue;
5050

51-
void VisitFieldAction(BuildContext context) => injections.PropertyInjection(variable.VariableName, context, property, propertyVariable);
51+
void VisitFieldAction(BuildContext context) => injections.PropertyInjection(context.Variable.VariableName, context, property, propertyVariable);
5252
}
5353

5454
foreach (var method in implementation.Methods)
@@ -58,7 +58,7 @@ public void Build(BuildContext ctx, in DpImplementation implementation)
5858
visits.Add((VisitMethodAction, method.Ordinal));
5959
continue;
6060

61-
void VisitMethodAction(BuildContext context) => injections.MethodInjection(variable.VariableName, context, method, methodArgs);
61+
void VisitMethodAction(BuildContext context) => injections.MethodInjection(context.Variable.VariableName, context, method, methodArgs);
6262
}
6363

6464
var onCreatedStatements = ctx.BuildTools.OnCreated(ctx, ctx.Variable).ToList();

tests/Pure.DI.IntegrationTests/FieldInjectionTests.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22

33
public class FieldInjectionTests
44
{
5-
[Fact]
6-
public async Task ShouldSupportFieldInjection()
5+
[Theory]
6+
[InlineData(Lifetime.Transient)]
7+
[InlineData(Lifetime.PerBlock)]
8+
[InlineData(Lifetime.Singleton)]
9+
[InlineData(Lifetime.Scoped)]
10+
[InlineData(Lifetime.PerResolve)]
11+
internal async Task ShouldSupportFieldInjection(Lifetime lifetime)
712
{
813
// Given
914

@@ -62,7 +67,7 @@ private static void SetupComposition()
6267
{
6368
DI.Setup("Composition")
6469
.Bind<IDependency>().To<Dependency>()
65-
.Bind<IService>().To<Service>()
70+
.Bind<IService>().As(Lifetime.#lifetime#).To<Service>()
6671
.Root<IService>("Service")
6772
.OrdinalAttribute<CustomOrdinalAttribute>();
6873
}
@@ -79,7 +84,7 @@ public static void Main()
7984
}
8085
}
8186
}
82-
""".RunAsync();
87+
""".Replace("#lifetime#", lifetime.ToString()).RunAsync();
8388

8489
// Then
8590
result.Success.ShouldBeTrue(result);

tests/Pure.DI.IntegrationTests/MethodInjectionTests.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22

33
public class MethodInjectionTests
44
{
5-
[Fact]
6-
public async Task ShouldSupportMethodInjection()
5+
[Theory]
6+
[InlineData(Lifetime.Transient, "Initialize dep", "Initialize dep", "Initialize", "False", "Activate")]
7+
[InlineData(Lifetime.PerBlock, "Initialize dep", "Initialize", "True", "Activate")]
8+
[InlineData(Lifetime.Singleton, "Initialize dep", "Initialize", "True", "Activate")]
9+
[InlineData(Lifetime.Scoped, "Initialize dep", "Initialize", "True", "Activate")]
10+
[InlineData(Lifetime.PerResolve, "Initialize dep", "Initialize", "True", "Activate")]
11+
internal async Task ShouldSupportMethodInjection(Lifetime lifetime, params string[] output)
712
{
813
// Given
914

@@ -55,7 +60,7 @@ public void Activate()
5560
internal void Initialize(IDependency dep)
5661
{
5762
Console.WriteLine("Initialize");
58-
Console.WriteLine(dep != Dep);
63+
Console.WriteLine(dep == Dep);
5964
}
6065
}
6166
@@ -64,7 +69,7 @@ static class Setup
6469
private static void SetupComposition()
6570
{
6671
DI.Setup("Composition")
67-
.Bind<IDependency>().To<Dependency>()
72+
.Bind<IDependency>().As(Lifetime.#lifetime#).To<Dependency>()
6873
.Bind<IService>().To<Service>()
6974
.Arg<string>("depName", 374)
7075
.Root<IService>("Service");
@@ -80,11 +85,11 @@ public static void Main()
8085
}
8186
}
8287
}
83-
""".RunAsync();
88+
""".Replace("#lifetime#", lifetime.ToString()).RunAsync();
8489

8590
// Then
8691
result.Success.ShouldBeTrue(result);
87-
result.StdOut.ShouldBe(["Initialize dep", "Initialize dep", "Initialize", "True", "Activate"], result);
92+
result.StdOut.ShouldBe([..output], result);
8893
}
8994

9095
[Fact]

tests/Pure.DI.IntegrationTests/PropertyInjectionTests.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
public class PropertyInjectionTests
44
{
5-
6-
[Fact]
7-
public async Task ShouldSupportInitPropertyInjection()
5+
[Theory]
6+
[InlineData(Lifetime.Transient)]
7+
[InlineData(Lifetime.PerBlock)]
8+
[InlineData(Lifetime.Singleton)]
9+
[InlineData(Lifetime.Scoped)]
10+
[InlineData(Lifetime.PerResolve)]
11+
internal async Task ShouldSupportInitPropertyInjection(Lifetime lifetime)
812
{
913
// Given
1014

@@ -74,7 +78,7 @@ private static void SetupComposition()
7478
{
7579
DI.Setup("Composition")
7680
.Bind<IDependency>().To<Dependency>()
77-
.Bind<IService>().To<Service>()
81+
.Bind<IService>().As(Lifetime.#lifetime#).To<Service>()
7882
.Root<IService>("Service")
7983
.OrdinalAttribute<CustomOrdinalAttribute>();
8084
}
@@ -89,14 +93,20 @@ public static void Main()
8993
}
9094
}
9195
}
92-
""".RunAsync(new Options(LanguageVersion.CSharp9));
96+
""".Replace("#lifetime#", lifetime.ToString()).RunAsync(new Options(LanguageVersion.CSharp9));
9397

9498
// Then
9599
result.Success.ShouldBeTrue(result);
96100
result.StdOut.ShouldBe(["OtherDep1", "True", "OtherDep0", "True"], result);
97101
}
98-
[Fact]
99-
public async Task ShouldSupportPropertyInjection()
102+
103+
[Theory]
104+
[InlineData(Lifetime.Transient)]
105+
[InlineData(Lifetime.PerBlock)]
106+
[InlineData(Lifetime.Singleton)]
107+
[InlineData(Lifetime.Scoped)]
108+
[InlineData(Lifetime.PerResolve)]
109+
internal async Task ShouldSupportPropertyInjection(Lifetime lifetime)
100110
{
101111
// Given
102112

@@ -166,7 +176,7 @@ private static void SetupComposition()
166176
{
167177
DI.Setup("Composition")
168178
.Bind<IDependency>().To<Dependency>()
169-
.Bind<IService>().To<Service>()
179+
.Bind<IService>().As(Lifetime.#lifetime#).To<Service>()
170180
.Root<IService>("Service")
171181
.OrdinalAttribute<CustomOrdinalAttribute>();
172182
}
@@ -181,7 +191,7 @@ public static void Main()
181191
}
182192
}
183193
}
184-
""".RunAsync();
194+
""".Replace("#lifetime#", lifetime.ToString()).RunAsync();
185195

186196
// Then
187197
result.Success.ShouldBeTrue(result);

0 commit comments

Comments
 (0)