Skip to content

Commit 78a8962

Browse files
authored
Merge pull request #148 from koenbeuk/issue-140
Fixed registration of multiple triggers of a shared type through ServiceCollectionExtensions
2 parents 5b31fe3 + 400ede7 commit 78a8962

File tree

2 files changed

+106
-6
lines changed

2 files changed

+106
-6
lines changed

src/EntityFrameworkCore.Triggered.Extensions/ServiceCollectionExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ static void RegisterTriggerTypes(Type triggerImplementationType, IServiceCollect
3434

3535
foreach (var customTrigger in customTriggers)
3636
{
37-
services.TryAdd(new ServiceDescriptor(customTrigger, sp => sp.GetRequiredService(triggerImplementationType), ServiceLifetime.Transient)); ;
37+
services.Add(new ServiceDescriptor(customTrigger, sp => sp.GetRequiredService(triggerImplementationType), ServiceLifetime.Transient)); ;
3838
}
3939
}
4040
}
4141

4242
public static IServiceCollection AddTrigger<TTrigger>(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Scoped)
4343
where TTrigger : class
4444
{
45-
services.Add(new ServiceDescriptor(typeof(TTrigger), typeof(TTrigger), lifetime));
45+
services.TryAdd(new ServiceDescriptor(typeof(TTrigger), typeof(TTrigger), lifetime));
4646

4747
RegisterTriggerTypes(typeof(TTrigger), services);
4848

@@ -51,7 +51,7 @@ public static IServiceCollection AddTrigger<TTrigger>(this IServiceCollection se
5151

5252
public static IServiceCollection AddTrigger(this IServiceCollection services, object triggerInstance)
5353
{
54-
services.AddSingleton(triggerInstance);
54+
services.TryAddSingleton(triggerInstance);
5555

5656
RegisterTriggerTypes(triggerInstance.GetType(), services);
5757

@@ -91,7 +91,7 @@ public static IServiceCollection AddAssemblyTriggers(this IServiceCollection ser
9191
{
9292
if (!registered)
9393
{
94-
services.Add(new ServiceDescriptor(assemblyType, assemblyType, lifetime));
94+
services.TryAdd(new ServiceDescriptor(assemblyType, assemblyType, lifetime));
9595

9696
registered = true;
9797
}

test/EntityFrameworkCore.Triggered.Extensions.Tests/ServiceCollectionExtensionsTests.cs

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,15 @@ public void AddAssemblyTriggers_WithAssembly_RegistersWithThatAssembly()
9191

9292
protected async Task SaveChanges_TriggeredAddedThroughDI_Template(Func<IServiceCollection, IServiceCollection> transform)
9393
{
94-
var serviceProvider = transform(new ServiceCollection()
94+
var services = transform(new ServiceCollection()
9595
.AddTriggeredDbContext<TestDbContext>(options => {
9696
options.UseInMemoryDatabase("test");
9797
options.ConfigureWarnings(warningOptions => {
9898
warningOptions.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning);
9999
});
100-
}))
100+
}));
101+
102+
var serviceProvider = services
101103
.BuildServiceProvider();
102104

103105
using var dbContext = serviceProvider.GetRequiredService<TestDbContext>();
@@ -132,5 +134,103 @@ public void AddAssemblyTriggers_AbstractTrigger_GetsIgnored()
132134
// Ensure that we did not register the AbstractTrigger
133135
Assert.Empty(serviceCollection.Where(x => x.ImplementationType == typeof(AbstractTrigger)));
134136
}
137+
138+
[Theory]
139+
[MemberData(nameof(Lifetimes))]
140+
public void AddTrigger_Multiple_AddsRegistrationForAll(ServiceLifetime lifetime)
141+
{
142+
var serviceCollection = new ServiceCollection()
143+
.AddTrigger<SampleTrigger>(lifetime)
144+
.AddTrigger<Trigger<object>>(lifetime);
145+
146+
Assert.Equal(9, serviceCollection.Count);
147+
}
148+
149+
[Theory]
150+
[MemberData(nameof(Lifetimes))]
151+
public void AddAssemblyTriggers_Multiple_AddsRegistrationForAll(ServiceLifetime lifetime)
152+
{
153+
var serviceCollection = new ServiceCollection()
154+
.AddTrigger<SampleTrigger>(lifetime)
155+
.AddAssemblyTriggers(typeof(Trigger<object>).Assembly);
156+
157+
Assert.Equal(9, serviceCollection.Count);
158+
}
159+
160+
[Fact]
161+
public void AddTriggerInstance_DoesNotDoubleRegister()
162+
{
163+
var trigger = new SampleTrigger();
164+
165+
var serviceCollection = new ServiceCollection()
166+
.AddTrigger(trigger)
167+
.AddTrigger(trigger);
168+
169+
Assert.Single(serviceCollection, x => x.ImplementationInstance == trigger);
170+
}
171+
172+
[Theory]
173+
[MemberData(nameof(Lifetimes))]
174+
public void AddTrigger_DoesNotDoubleRegister(ServiceLifetime lifetime)
175+
{
176+
var serviceCollection = new ServiceCollection()
177+
.AddTrigger<SampleTrigger>(lifetime)
178+
.AddTrigger<SampleTrigger>(lifetime);
179+
180+
Assert.Single(serviceCollection, x => x.ServiceType == typeof(SampleTrigger));
181+
}
182+
183+
[Theory]
184+
[MemberData(nameof(Lifetimes))]
185+
public void AddTrigger_DoesNotDoubleRegister2(ServiceLifetime lifetime)
186+
{
187+
var serviceCollection = new ServiceCollection()
188+
.AddAssemblyTriggers(lifetime)
189+
.AddTrigger<SampleTrigger>(lifetime);
190+
191+
Assert.Single(serviceCollection, x => x.ServiceType == typeof(SampleTrigger));
192+
}
193+
194+
[Theory]
195+
[MemberData(nameof(Lifetimes))]
196+
public void AddAssemblyTrigger_DoesNotDoubleRegister(ServiceLifetime lifetime)
197+
{
198+
var serviceCollection = new ServiceCollection()
199+
.AddAssemblyTriggers(lifetime)
200+
.AddAssemblyTriggers(lifetime);
201+
202+
Assert.Single(serviceCollection, x => x.ServiceType == typeof(SampleTrigger));
203+
}
204+
205+
[Theory]
206+
[MemberData(nameof(Lifetimes))]
207+
public void AddAssemblyTrigger_DoesNotDoubleRegister2(ServiceLifetime lifetime)
208+
{
209+
var serviceCollection = new ServiceCollection()
210+
.AddTrigger<SampleTrigger>(lifetime)
211+
.AddAssemblyTriggers(lifetime);
212+
213+
Assert.Single(serviceCollection, x => x.ServiceType == typeof(SampleTrigger));
214+
}
215+
216+
[Fact]
217+
public void AddTrigger_WhenExplicitlyRegisteredAsAService_OnlyAddsTheTriggerTypeRegistrations()
218+
{
219+
var serviceCollection = new ServiceCollection()
220+
.AddSingleton<SampleTrigger>()
221+
.AddTrigger<SampleTrigger>();
222+
223+
Assert.Equal(5, serviceCollection.Count);
224+
}
225+
226+
[Fact]
227+
public void AddAssemblyTriggers_WhenExplicitlyRegisteredAsAService_OnlyAddsTheTriggerTypeRegistrations()
228+
{
229+
var serviceCollection = new ServiceCollection()
230+
.AddSingleton<SampleTrigger>()
231+
.AddAssemblyTriggers();
232+
233+
Assert.Equal(5, serviceCollection.Count);
234+
}
135235
}
136236
}

0 commit comments

Comments
 (0)