Skip to content

Commit b91b1da

Browse files
committed
use scope store
1 parent 8986c26 commit b91b1da

File tree

6 files changed

+66
-12
lines changed

6 files changed

+66
-12
lines changed

.editorconfig

+2
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,5 @@ dotnet_diagnostic.CA1040.severity = none
213213

214214
# CA1031: Do not catch general exception types
215215
dotnet_diagnostic.CA1031.severity = none
216+
217+
dotnet_diagnostic.S3011.severity = none

MainProject/Injecter.Wpf/XamlInjecter.cs

+15-10
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ private static void DoInjectionScoped(DependencyObject d, DependencyPropertyChan
3232

3333
if (CompositionRoot.ServiceProvider is null) return;
3434

35-
var scope = CompositionRoot.ServiceProvider.GetRequiredService<IInjecter>().InjectIntoType(d.GetType(), d);
35+
CompositionRoot.ServiceProvider
36+
.GetRequiredService<IInjecter>()
37+
.InjectIntoType(d.GetType(), d);
3638

3739
var behavior = (DisposeBehaviour?)e.NewValue;
3840

@@ -49,13 +51,14 @@ void OnLoaded(object sender, EventArgs eventArgs)
4951

5052
var window = Window.GetWindow(d);
5153

52-
void OnWindowClosed(object _, EventArgs __)
54+
void OnWindowClosed(object? _, EventArgs __)
5355
{
5456
window.Closed -= OnWindowClosed;
5557
window = null;
5658

57-
scope!.Dispose();
58-
scope = null;
59+
CompositionRoot.ServiceProvider
60+
.GetRequiredService<IScopeStore>()
61+
.DisposeScope(d);
5962

6063
if (d is IDisposable disposable) disposable.Dispose();
6164
d = null!;
@@ -70,12 +73,13 @@ void OnWindowClosed(object _, EventArgs __)
7073
}
7174
case DisposeBehaviour.OnDispatcherShutdown:
7275
{
73-
void OnControlShutdown(object sender, EventArgs eventArgs)
76+
void OnControlShutdown(object? sender, EventArgs __)
7477
{
7578
Application.Current.Dispatcher.ShutdownFinished -= OnControlShutdown;
7679

77-
scope!.Dispose();
78-
scope = null;
80+
CompositionRoot.ServiceProvider
81+
.GetRequiredService<IScopeStore>()
82+
.DisposeScope(d);
7983

8084
if (d is IDisposable disposable) disposable.Dispose();
8185
d = null!;
@@ -89,13 +93,14 @@ void OnControlShutdown(object sender, EventArgs eventArgs)
8993
{
9094
if (d is not FrameworkElement f) throw new InvalidOperationException($"{d} is not of type {nameof(FrameworkElement)}");
9195

92-
void OnControlUnloaded(object sender, RoutedEventArgs routedEventArgs)
96+
void OnControlUnloaded(object? _, RoutedEventArgs __)
9397
{
9498
f.Unloaded -= OnControlUnloaded;
9599
f = null!;
96100

97-
scope!.Dispose();
98-
scope = null;
101+
CompositionRoot.ServiceProvider
102+
.GetRequiredService<IScopeStore>()
103+
.DisposeScope(d);
99104

100105
if (d is IDisposable disposable) disposable.Dispose();
101106
d = null!;

MainProject/Injecter/IScopeStore.cs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
3+
namespace Injecter
4+
{
5+
public interface IScopeStore
6+
{
7+
IServiceScope CreateScope(object owner);
8+
void DisposeScope(object owner);
9+
IServiceScope GetScope(object owner);
10+
}
11+
}

MainProject/Injecter/Injecter.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ public sealed class Injecter : IInjecter
1212
private readonly ConcurrentDictionary<Type, (FieldInfo[] fieldInfos, PropertyInfo[] propertyInfos, MethodInfo[] methodInfos)> _resolveDictionary = new();
1313

1414
private readonly InjecterOptions _options;
15+
private readonly IScopeStore _scopeStore;
1516
private readonly IServiceProvider _serviceProvider;
1617

17-
public Injecter(IServiceProvider serviceProvider, InjecterOptions options)
18+
public Injecter(IServiceProvider serviceProvider, InjecterOptions options, IScopeStore scopeStore)
1819
{
1920
_serviceProvider = serviceProvider;
2021
_options = options;
22+
_scopeStore = scopeStore;
2123
}
2224

2325
public IServiceScope? InjectIntoType(Type type, object instance, bool createScope = true)
@@ -27,7 +29,7 @@ public Injecter(IServiceProvider serviceProvider, InjecterOptions options)
2729

2830
var (fieldInfos, propertyInfos, methodInfos) = GetMembers(type);
2931

30-
IServiceScope? serviceScope = createScope ? _serviceProvider.CreateScope() : null;
32+
IServiceScope? serviceScope = createScope ? _scopeStore.CreateScope(instance) : null;
3133
var serviceProvider = createScope switch
3234
{
3335
true => serviceScope!.ServiceProvider,

MainProject/Injecter/InjecterExtensions.cs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public static IServiceCollection AddInjecter(this IServiceCollection services, A
1515

1616
services.AddSingleton(options);
1717
services.AddSingleton<IInjecter, Injecter>();
18+
services.AddSingleton<IScopeStore, ScopeStore>();
1819

1920
return services;
2021
}

MainProject/Injecter/ScopeStore.cs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using System;
3+
using System.Collections.Generic;
4+
5+
namespace Injecter
6+
{
7+
public sealed class ScopeStore : IScopeStore
8+
{
9+
private readonly IServiceProvider _serviceProvider;
10+
private readonly Dictionary<object, IServiceScope> _scopes = new();
11+
12+
public ScopeStore(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider;
13+
14+
public IServiceScope CreateScope(object owner)
15+
{
16+
var scope = _serviceProvider.CreateScope();
17+
_scopes.Add(owner, scope);
18+
19+
return scope;
20+
}
21+
22+
public IServiceScope GetScope(object owner) => _scopes[owner];
23+
24+
public void DisposeScope(object owner)
25+
{
26+
var scope = _scopes[owner];
27+
28+
scope.Dispose();
29+
30+
_scopes.Remove(owner);
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)