Skip to content

Commit bed99b0

Browse files
authored
Provide service provider to subscription execution (#691)
1 parent 37fd20d commit bed99b0

File tree

4 files changed

+57
-11
lines changed

4 files changed

+57
-11
lines changed

src/Transports.Subscriptions.Abstractions/SubscriptionManager.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using GraphQL.NewtonsoftJson;
88
using GraphQL.Server.Transports.Subscriptions.Abstractions.Internal;
99
using GraphQL.Subscription;
10+
using Microsoft.Extensions.DependencyInjection;
1011
using Microsoft.Extensions.Logging;
1112

1213
namespace GraphQL.Server.Transports.Subscriptions.Abstractions
@@ -17,17 +18,24 @@ public class SubscriptionManager : ISubscriptionManager, IDisposable
1718
private readonly IGraphQLExecuter _executer;
1819

1920
private readonly ILogger<SubscriptionManager> _logger;
21+
private readonly IServiceScopeFactory _serviceScopeFactory;
2022
private readonly ILoggerFactory _loggerFactory;
2123
private volatile bool _disposed;
2224

23-
private readonly ConcurrentDictionary<string, Subscription> _subscriptions =
24-
new ConcurrentDictionary<string, Subscription>();
25+
private readonly ConcurrentDictionary<string, Subscription> _subscriptions = new();
2526

27+
[Obsolete]
2628
public SubscriptionManager(IGraphQLExecuter executer, ILoggerFactory loggerFactory)
29+
: this(executer, loggerFactory, NoopServiceScopeFactory.Instance)
30+
{
31+
}
32+
33+
public SubscriptionManager(IGraphQLExecuter executer, ILoggerFactory loggerFactory, IServiceScopeFactory serviceScopeFactory)
2734
{
2835
_executer = executer;
2936
_loggerFactory = loggerFactory;
3037
_logger = loggerFactory.CreateLogger<SubscriptionManager>();
38+
_serviceScopeFactory = serviceScopeFactory;
3139
}
3240

3341
public Subscription this[string id] => _subscriptions[id];
@@ -82,13 +90,17 @@ private async Task<Subscription> ExecuteAsync(
8290
payload.OperationName,
8391
payload.Query);
8492

85-
var result = await _executer.ExecuteAsync(
86-
payload.OperationName,
87-
payload.Query,
88-
payload.Variables?.ToInputs(),
89-
context,
90-
null // TODO: find later a better way to specify services
91-
).ConfigureAwait(false);
93+
ExecutionResult result;
94+
using (var scope = _serviceScopeFactory.CreateScope())
95+
{
96+
result = await _executer.ExecuteAsync(
97+
payload.OperationName,
98+
payload.Query,
99+
payload.Variables?.ToInputs(),
100+
context,
101+
scope.ServiceProvider
102+
).ConfigureAwait(false);
103+
}
92104

93105
if (result.Errors != null && result.Errors.Any())
94106
{
@@ -169,5 +181,14 @@ public virtual void Dispose()
169181
}
170182
}
171183
}
184+
185+
private sealed class NoopServiceScopeFactory : IServiceScopeFactory, IServiceScope
186+
{
187+
public static IServiceScopeFactory Instance { get; } = new NoopServiceScopeFactory();
188+
private NoopServiceScopeFactory() { }
189+
IServiceScope IServiceScopeFactory.CreateScope() => this;
190+
IServiceProvider IServiceScope.ServiceProvider => null;
191+
void IDisposable.Dispose() { }
192+
}
172193
}
173194
}

src/Transports.Subscriptions.WebSockets/WebSocketConnectionFactory.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Net.WebSockets;
34
using GraphQL.Server.Transports.Subscriptions.Abstractions;
45
using GraphQL.Types;
6+
using Microsoft.Extensions.DependencyInjection;
57
using Microsoft.Extensions.Logging;
68

79
namespace GraphQL.Server.Transports.WebSockets
@@ -14,26 +16,45 @@ public class WebSocketConnectionFactory<TSchema> : IWebSocketConnectionFactory<T
1416
private readonly IGraphQLExecuter<TSchema> _executer;
1517
private readonly IEnumerable<IOperationMessageListener> _messageListeners;
1618
private readonly IDocumentWriter _documentWriter;
19+
private readonly IServiceScopeFactory _serviceScopeFactory;
1720

18-
public WebSocketConnectionFactory(ILogger<WebSocketConnectionFactory<TSchema>> logger,
21+
[Obsolete]
22+
public WebSocketConnectionFactory(
23+
ILogger<WebSocketConnectionFactory<TSchema>> logger,
1924
ILoggerFactory loggerFactory,
2025
IGraphQLExecuter<TSchema> executer,
2126
IEnumerable<IOperationMessageListener> messageListeners,
2227
IDocumentWriter documentWriter)
28+
: this(logger, loggerFactory, executer, messageListeners, documentWriter, null)
29+
{
30+
}
31+
32+
public WebSocketConnectionFactory(
33+
ILogger<WebSocketConnectionFactory<TSchema>> logger,
34+
ILoggerFactory loggerFactory,
35+
IGraphQLExecuter<TSchema> executer,
36+
IEnumerable<IOperationMessageListener> messageListeners,
37+
IDocumentWriter documentWriter,
38+
IServiceScopeFactory serviceScopeFactory)
2339
{
2440
_logger = logger;
2541
_loggerFactory = loggerFactory;
2642
_executer = executer;
2743
_messageListeners = messageListeners;
2844
_documentWriter = documentWriter;
45+
_serviceScopeFactory = serviceScopeFactory;
2946
}
3047

3148
public WebSocketConnection CreateConnection(WebSocket socket, string connectionId)
3249
{
3350
_logger.LogDebug("Creating server for connection {connectionId}", connectionId);
3451

3552
var transport = new WebSocketTransport(socket, _documentWriter);
36-
var manager = new SubscriptionManager(_executer, _loggerFactory);
53+
var manager = _serviceScopeFactory != null
54+
? new SubscriptionManager(_executer, _loggerFactory, _serviceScopeFactory)
55+
#pragma warning disable CS0612 // Type or member is obsolete
56+
: new SubscriptionManager(_executer, _loggerFactory);
57+
#pragma warning restore CS0612 // Type or member is obsolete
3758
var server = new SubscriptionServer(
3859
transport,
3960
manager,

tests/ApiApprovalTests/GraphQL.Server.Transports.Subscriptions.Abstractions.approved.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ namespace GraphQL.Server.Transports.Subscriptions.Abstractions
109109
}
110110
public class SubscriptionManager : GraphQL.Server.Transports.Subscriptions.Abstractions.ISubscriptionManager, System.Collections.Generic.IEnumerable<GraphQL.Server.Transports.Subscriptions.Abstractions.Subscription>, System.Collections.IEnumerable, System.IDisposable
111111
{
112+
[System.Obsolete]
112113
public SubscriptionManager(GraphQL.Server.IGraphQLExecuter executer, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
114+
public SubscriptionManager(GraphQL.Server.IGraphQLExecuter executer, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory) { }
113115
public GraphQL.Server.Transports.Subscriptions.Abstractions.Subscription this[string id] { get; }
114116
public virtual void Dispose() { }
115117
public System.Collections.Generic.IEnumerator<GraphQL.Server.Transports.Subscriptions.Abstractions.Subscription> GetEnumerator() { }

tests/ApiApprovalTests/GraphQL.Server.Transports.Subscriptions.WebSockets.approved.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ namespace GraphQL.Server.Transports.WebSockets
2929
public class WebSocketConnectionFactory<TSchema> : GraphQL.Server.Transports.WebSockets.IWebSocketConnectionFactory<TSchema>
3030
where TSchema : GraphQL.Types.ISchema
3131
{
32+
[System.Obsolete]
3233
public WebSocketConnectionFactory(Microsoft.Extensions.Logging.ILogger<GraphQL.Server.Transports.WebSockets.WebSocketConnectionFactory<TSchema>> logger, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, GraphQL.Server.IGraphQLExecuter<TSchema> executer, System.Collections.Generic.IEnumerable<GraphQL.Server.Transports.Subscriptions.Abstractions.IOperationMessageListener> messageListeners, GraphQL.IDocumentWriter documentWriter) { }
34+
public WebSocketConnectionFactory(Microsoft.Extensions.Logging.ILogger<GraphQL.Server.Transports.WebSockets.WebSocketConnectionFactory<TSchema>> logger, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, GraphQL.Server.IGraphQLExecuter<TSchema> executer, System.Collections.Generic.IEnumerable<GraphQL.Server.Transports.Subscriptions.Abstractions.IOperationMessageListener> messageListeners, GraphQL.IDocumentWriter documentWriter, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory) { }
3335
public GraphQL.Server.Transports.WebSockets.WebSocketConnection CreateConnection(System.Net.WebSockets.WebSocket socket, string connectionId) { }
3436
}
3537
public class WebSocketReaderPipeline : GraphQL.Server.Transports.Subscriptions.Abstractions.IReaderPipeline

0 commit comments

Comments
 (0)