Introduce scope DIs to routing handlers

This commit is contained in:
Alexandru Macocian
2021-10-02 08:18:53 +02:00
parent 8eb0fe06c0
commit 14e96ab206
9 changed files with 84 additions and 36 deletions
@@ -7,8 +7,10 @@ using System.Threading.Tasks;
namespace MTSC.Common.Http.RoutingModules
{
public abstract class HttpRouteBase : ISetHttpContext
public abstract class HttpRouteBase : ISetHttpContext, IDisposable
{
private bool disposedValue;
private static HttpResponse InternalServerError500 { get; } =
new HttpResponse
{
@@ -19,6 +21,7 @@ namespace MTSC.Common.Http.RoutingModules
public ClientData ClientData { get; private set; }
public HttpRoutingHandler HttpRoutingHandler { get; private set; }
public Server Server { get; private set; }
public Slim.IServiceProvider ScopedServiceProvider { get; private set; }
public async Task<HttpResponse> CallHandleRequest(HttpRequest request)
{
@@ -38,6 +41,10 @@ namespace MTSC.Common.Http.RoutingModules
}
public abstract Task<HttpResponse> HandleRequest(HttpRequest request);
void ISetHttpContext.SetScopedServiceProvider(Slim.IServiceProvider serviceProvider)
{
this.ScopedServiceProvider = serviceProvider;
}
void ISetHttpContext.SetClientData(ClientData clientData)
{
this.ClientData = clientData;
@@ -50,6 +57,25 @@ namespace MTSC.Common.Http.RoutingModules
{
this.Server = server;
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
this.disposedValue = true;
if (disposing)
{
this.ScopedServiceProvider.Dispose();
}
this.ScopedServiceProvider = null;
}
}
public void Dispose()
{
this.Dispose(disposing: true);
}
}
public abstract class HttpRouteBase<T> : HttpRouteBase
{
@@ -1,5 +1,6 @@
using MTSC.ServerSide;
using MTSC.ServerSide.Handlers;
using Slim;
namespace MTSC.Common.Http.RoutingModules
{
@@ -8,5 +9,6 @@ namespace MTSC.Common.Http.RoutingModules
void SetClientData(ClientData clientData);
void SetServer(Server server);
void SetHttpRoutingHandler(HttpRoutingHandler httpRoutingHandler);
void SetScopedServiceProvider(IServiceProvider serviceProvider);
}
}
@@ -1,5 +1,6 @@
using MTSC.ServerSide;
using MTSC.ServerSide.Handlers;
using Slim;
namespace MTSC.Common.WebSockets.RoutingModules
{
@@ -8,5 +9,6 @@ namespace MTSC.Common.WebSockets.RoutingModules
void SetServer(Server server);
void SetHandler(WebsocketRoutingHandler websocketRoutingHandler);
void SetClient(ClientData clientData);
void SetScopedServiceProvider(IServiceProvider serviceProvider);
}
}
@@ -6,11 +6,14 @@ using System.Text;
namespace MTSC.Common.WebSockets.RoutingModules
{
public abstract class WebsocketRouteBase : ISetWebsocketContext
public abstract class WebsocketRouteBase : ISetWebsocketContext, IDisposable
{
private bool disposedValue;
protected Server Server { get; private set; }
protected WebsocketRoutingHandler WebsocketRoutingHandler { get; private set; }
protected ClientData ClientData { get; private set; }
protected Slim.IServiceProvider ScopedServiceProvider { get; private set; }
public void CallConnectionInitialized()
{
@@ -47,6 +50,11 @@ namespace MTSC.Common.WebSockets.RoutingModules
this.ClientData = clientData;
}
void ISetWebsocketContext.SetScopedServiceProvider(Slim.IServiceProvider serviceProvider)
{
this.ScopedServiceProvider = serviceProvider;
}
internal static IWebsocketMessageConverter<T> GetStringAdhocConverter<T>()
{
return new AdhocConverter<T>(
@@ -74,6 +82,24 @@ namespace MTSC.Common.WebSockets.RoutingModules
};
});
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
this.disposedValue = true;
if (disposing)
{
this.ScopedServiceProvider.Dispose();
this.ScopedServiceProvider = null;
}
}
}
public void Dispose()
{
this.Dispose(disposing: true);
}
}
public abstract class WebsocketRouteBase<TReceive> : WebsocketRouteBase
{
+4 -4
View File
@@ -5,13 +5,13 @@
<TargetFrameworks>netcoreapp2.1;net48;netstandard2.0;netcoreapp3.1;net5.0</TargetFrameworks>
<ApplicationIcon />
<StartupObject />
<Version>4.3.0</Version>
<Version>4.4.0</Version>
<LangVersion>latest</LangVersion>
<Authors>Alexandru-Victor Macocian</Authors>
<Product>MTSC</Product>
<Description>Modular TCP Server and Client</Description>
<AssemblyVersion>4.3.0.0</AssemblyVersion>
<FileVersion>4.3.0.0</FileVersion>
<AssemblyVersion>4.4.0.0</AssemblyVersion>
<FileVersion>4.4.0.0</FileVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Platforms>AnyCPU;x64</Platforms>
<PackageProjectUrl>https://github.com/AlexMacocian/MTSC</PackageProjectUrl>
@@ -29,7 +29,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Slim" Version="1.5.2" />
<PackageReference Include="Slim" Version="1.5.4" />
</ItemGroup>
<ItemGroup>
+3 -16
View File
@@ -115,31 +115,18 @@ namespace MTSC.ServerSide
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
this.SafeNetworkStream?.Dispose();
this.SslStream?.Dispose();
this.Resources?.Dispose();
}
this.SafeNetworkStream?.Dispose();
this.SslStream?.Dispose();
this.Resources?.Dispose();
this.disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~ClientData()
// {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
this.Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
@@ -189,7 +189,8 @@ namespace MTSC.ServerSide.Handlers
{
if (this.TryMatchUrl(request.Method, request.RequestURI, out var urlValues, out var routeType, out var routeEnabler))
{
var module = this.GetRoute(routeType, client, server);
var scopedServiceProvider = server.ServiceManager.CreateScope();
var module = this.GetRoute(scopedServiceProvider, routeType, client, server);
if (request.Complete)
{
var httpRequest = request.ToRequest();
@@ -282,7 +283,7 @@ namespace MTSC.ServerSide.Handlers
httpLogger.LogResponse(server, this, client, task.Result);
}
this.QueueResponse(client, task.Result);
this.QueueResponse(client, task.Result);
});
}
catch (Exception e)
@@ -339,17 +340,19 @@ namespace MTSC.ServerSide.Handlers
public Func<Server, HttpRequest, ClientData, RouteEnablerResponse> RouteEnabler { get; set; }
}
private HttpRouteBase GetRoute(Type routeType, ClientData client, Server server)
private HttpRouteBase GetRoute(Slim.IServiceProvider serviceProvider, Type routeType, ClientData client, Server server)
{
if (!typeof(HttpRouteBase).IsAssignableFrom(routeType))
{
throw new InvalidOperationException($"Cannot create new route of type {routeType.FullName}. Not of type {typeof(HttpRouteBase).FullName}");
}
var module = server.ServiceManager.GetService(routeType) as HttpRouteBase;
var module = serviceProvider.GetService(routeType) as HttpRouteBase;
(module as ISetHttpContext).SetClientData(client);
(module as ISetHttpContext).SetServer(server);
(module as ISetHttpContext).SetHttpRoutingHandler(this);
(module as ISetHttpContext).SetScopedServiceProvider(serviceProvider);
client.Resources.SetResource(module);
return module;
}
@@ -189,7 +189,8 @@ namespace MTSC.ServerSide.Handlers
/*
* Create and assign route module to client.
*/
if (server.ServiceManager.GetService(moduleType) is not WebsocketRouteBase module)
var scopedServiceManager = server.ServiceManager.CreateScope();
if (scopedServiceManager.GetService(moduleType) is not WebsocketRouteBase module)
{
throw new InvalidOperationException($"Unexpected error during websocket module initialization. {moduleType.FullName} is not of type {typeof(WebsocketRouteBase).FullName}");
}
@@ -197,6 +198,7 @@ namespace MTSC.ServerSide.Handlers
(module as ISetWebsocketContext).SetClient(client);
(module as ISetWebsocketContext).SetHandler(this);
(module as ISetWebsocketContext).SetServer(server);
(module as ISetWebsocketContext).SetScopedServiceProvider(scopedServiceManager);
client.Resources.SetResource(module);
module.CallConnectionInitialized();
return true;
@@ -304,7 +306,7 @@ namespace MTSC.ServerSide.Handlers
{
foreach((var routeType, _) in this.moduleDictionary.Values)
{
server.ServiceManager.RegisterTransient(routeType, routeType);
server.ServiceManager.RegisterScoped(routeType, routeType);
}
}
#endregion
+8 -8
View File
@@ -58,16 +58,16 @@ namespace MTSC.ServerSide
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
foreach (var value in this.Resources.Values)
{
(value as IDisposable)?.Dispose();
}
this.Resources.Clear();
this.Resources = null;
}
foreach(var value in this.Resources.Values)
{
(value as IDisposable)?.Dispose();
}
this.Resources.Clear();
this.Resources = null;
this.disposedValue = true;
}
}