Skip to content

Commit 4d28864

Browse files
committed
Resolve #916: IStartable that creates child lifetime scope during Start no longer tries to activate itself.
1 parent 493b020 commit 4d28864

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

src/Autofac/Core/Resolving/InstanceLookup.cs

+5-8
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,11 @@ private void StartStartableComponent(object instance)
9696
&& !ComponentRegistration.Metadata.ContainsKey(MetadataKeys.AutoActivated)
9797
&& ComponentRegistry.Properties.ContainsKey(MetadataKeys.StartOnActivatePropertyKey))
9898
{
99-
try
100-
{
101-
startable.Start();
102-
}
103-
finally
104-
{
105-
ComponentRegistration.Metadata[MetadataKeys.AutoActivated] = true;
106-
}
99+
// Issue #916: Set the startable as "done starting" BEFORE calling Start
100+
// so you don't get a StackOverflow if the component creates a child scope
101+
// during Start. You don't want the startable trying to activate itself.
102+
ComponentRegistration.Metadata[MetadataKeys.AutoActivated] = true;
103+
startable.Start();
107104
}
108105
}
109106

test/Autofac.Test/StartableTests.cs

+39
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ public void WhenStartIsSpecified_StartableComponentsAreStarted()
5151
Assert.True(startable.StartCount > 0);
5252
}
5353

54+
[Fact]
55+
public void WhenStartableCreatesChildScope_NoExceptionIsThrown()
56+
{
57+
// Issue #916
58+
var builder = new ContainerBuilder();
59+
builder.RegisterType<StartableCreatesLifetimeScope>().As<IStartable>().SingleInstance();
60+
var container = builder.Build();
61+
}
62+
5463
[Theory]
5564
[InlineData(true)]
5665
[InlineData(false)]
@@ -139,6 +148,36 @@ public void Start()
139148
}
140149
}
141150

151+
// Issue #916
152+
private class StartableCreatesLifetimeScope : IStartable
153+
{
154+
private readonly ILifetimeScope _scope;
155+
156+
public StartableCreatesLifetimeScope(ILifetimeScope scope)
157+
{
158+
this._scope = scope;
159+
}
160+
161+
public void Start()
162+
{
163+
using (var nested = this._scope.BeginLifetimeScope("tag", b => { }))
164+
{
165+
}
166+
167+
using (var nested = this._scope.BeginLifetimeScope(b => { }))
168+
{
169+
}
170+
171+
using (var nested = this._scope.BeginLifetimeScope("tag"))
172+
{
173+
}
174+
175+
using (var nested = this._scope.BeginLifetimeScope())
176+
{
177+
}
178+
}
179+
}
180+
142181
private class StartableDependency : IStartableDependency
143182
{
144183
private static int _count = 0;

0 commit comments

Comments
 (0)