First backend rewrite to Microsoft Dependency injection

This commit is contained in:
2025-07-11 23:18:24 +03:00
parent e7e0cbac05
commit 3f7b504971
50 changed files with 233 additions and 490 deletions
+4
View File
@@ -22,4 +22,8 @@
<ProjectReference Include="..\Example.Shared\Example.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
</ItemGroup>
</Project>
+37 -29
View File
@@ -8,53 +8,61 @@ using mROA.Cbor;
using mROA.Codegen;
using mROA.Implementation;
using mROA.Implementation.Backend;
using mROA.Implementation.Bootstrap;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
class Program
{
public static void Main(string[] args)
{
var builder = new FullMixBuilder();
// builder.UseJsonSerialisation();
builder.Modules.Add(new CborSerializationToolkit());
builder.Modules.Add(new BackendIdentityGenerator());
// builder.UseNetworkGateway(new IPEndPoint(IPAddress.Loopback, 4567), typeof(NextGenerationInteractionModule),
// builder.GetModule<IIdentityGenerator>()!);
var builder = Host.CreateApplicationBuilder();
builder.Services.AddSingleton<IContextualSerializationToolKit, CborSerializationToolkit>();
builder.Services.AddSingleton<IIdentityGenerator, BackendIdentityGenerator>();
builder.Services.AddSingleton<IGatewayModule, NetworkGatewayModule>();
builder.Services.AddSingleton<IUntrustedGateway, UdpGateway>();
builder.Services.AddSingleton<IConnectionHub, ConnectionHub>();
builder.Services.AddOptions();
var listening = new IPEndPoint(IPAddress.Any, 4567);
builder.UseNetworkGateway(listening, typeof(ChannelInteractionModule),
builder.GetModule<IIdentityGenerator>()!);
builder.Modules.Add(new UdpGateway(listening));
builder.Modules.Add(new ConnectionHub());
builder.Modules.Add(new HubRequestExtractor());
builder.UseBasicExecution();
builder.Modules.Add(new CreativeRepresentationModuleProducer(
new IInjectableModule[] { builder.GetModule<IContextualSerializationToolKit>()! },
typeof(RepresentationModule)));
builder.Modules.Add(new RemoteInstanceRepository());
// builder.UseCollectableContextRepository(typeof(PrinterFactory).Assembly);
builder.Modules.Add(new MultiClientInstanceRepository(i =>
builder.Services.Configure<GatewayOptions>(options => options.Endpoint = listening);
builder.Services.AddSingleton<HubRequestExtractor>();
builder.Services.AddSingleton<IExecuteModule, BasicExecutionModule>();
builder.Services.AddSingleton<IRepresentationModuleProducer, CreativeRepresentationModuleProducer>();
builder.Services.AddSingleton<IInstanceRepository, RemoteInstanceRepository>();
builder.Services.AddSingleton<IRealStoreInstanceRepository>(provider => new MultiClientInstanceRepository(i =>
{
var repo = new InstanceRepository();
var producer = provider.GetService<IRepresentationModuleProducer>();
var repo = new InstanceRepository(producer);
repo.FillSingletons(typeof(PrinterFactory).Assembly);
repo.Inject(builder.Modules.OfType<CreativeRepresentationModuleProducer>().First());
return repo;
}));
builder.Services.AddSingleton<IMethodRepository>(p =>
{
var methodRepo = new CollectableMethodRepository();
methodRepo.AppendInvokers(new GeneratedInvokersCollection());
builder.Modules.Add(methodRepo);
builder.Modules.Add(new GeneratedCallIndexProvider());
builder.Modules.Add(new GeneratedCallIndexProvider());
builder.Modules.Add(new CancellationRepository());
return methodRepo;
});
builder.Services.AddSingleton<ICallIndexProvider, GeneratedCallIndexProvider>();
builder.Build();
new RemoteTypeBinder();
builder.Services.AddSingleton<ICancellationRepository, CancellationRepository>();
var mroaMachine = builder.Build();
_ = builder.GetModule<UdpGateway>()!.Start();
var gateway = builder.GetModule<IGatewayModule>();
mroaMachine.StartAsync();
//
// builder.Build();
// new RemoteTypeBinder();
//
//
_ = mroaMachine.Services.GetService<IUntrustedGateway>()!.Start();
var gateway = mroaMachine.Services.GetService<IGatewayModule>();
gateway.Run();
Console.ReadLine();
}
}
+4
View File
@@ -21,4 +21,8 @@
<ProjectReference Include="..\Example.Shared\Example.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
</ItemGroup>
</Project>
+4
View File
@@ -13,4 +13,8 @@
<ProjectReference Include="..\Example.Shared\Example.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
</ItemGroup>
</Project>
+1
View File
@@ -14,6 +14,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.7" />
<PackageReference Include="mROA.Codegen" Version="2.0.5" />
</ItemGroup>
-1
View File
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Formats.Cbor;
using mROA.Abstract;
using mROA.Implementation;
+1 -1
View File
@@ -5,7 +5,7 @@ using mROA.Implementation;
namespace mROA.Abstract
{
public interface ICallIndexProvider : IInjectableModule
public interface ICallIndexProvider
{
Dictionary<Type, Func<int, IRepresentationModule, IEndPointContext, int[], RemoteObjectBase>> Activators
{
+1 -1
View File
@@ -3,7 +3,7 @@ using System.Threading;
namespace mROA.Abstract
{
public interface ICancellationRepository : IInjectableModule
public interface ICancellationRepository
{
void RegisterCancellation(Guid id, CancellationTokenSource cts);
CancellationTokenSource? GetCancellation(Guid id);
+2 -2
View File
@@ -5,10 +5,10 @@ using mROA.Implementation;
namespace mROA.Abstract
{
public interface IChannelInteractionModule : IInjectableModule, IDisposable
public interface IChannelInteractionModule : IDisposable
{
int ConnectionId { get; set; }
IEndPointContext Context { get; }
IEndPointContext Context { get; set; }
Channel<NetworkMessageHeader> ReceiveChanel { get; }
ChannelReader<NetworkMessageHeader> TrustedPostChanel { get; }
ChannelReader<NetworkMessageHeader> UntrustedPostChanel { get; }
+1 -1
View File
@@ -4,7 +4,7 @@
public delegate void DisconnectionHandler(IRepresentationModule representationModule);
public interface IConnectionHub : IInjectableModule
public interface IConnectionHub
{
void RegisterInteraction(IChannelInteractionModule interaction);
IChannelInteractionModule GetInteraction(int id);
@@ -2,7 +2,7 @@
namespace mROA.Abstract
{
public interface IContextualSerializationToolKit : IInjectableModule
public interface IContextualSerializationToolKit
{
byte[] Serialize(object objectToSerialize, IEndPointContext? context);
int Serialize(object objectToSerialize, Span<byte> destination, IEndPointContext? context);
+1 -1
View File
@@ -1,6 +1,6 @@
namespace mROA.Abstract
{
public interface IEndPointContext : IInjectableModule
public interface IEndPointContext
{
IInstanceRepository RealRepository { get; set; }
IInstanceRepository RemoteRepository { get; set; }
+1 -1
View File
@@ -2,7 +2,7 @@ using mROA.Implementation;
namespace mROA.Abstract
{
public interface IExecuteModule : IInjectableModule
public interface IExecuteModule
{
ICommandExecution Execute(ICallRequest command, IInstanceRepository instanceRepository,
IRepresentationModule representationModule, IEndPointContext context);
+1 -1
View File
@@ -3,7 +3,7 @@ using System.Threading.Tasks;
namespace mROA.Abstract
{
public interface IFrontendBridge : IInjectableModule, IDisposable
public interface IFrontendBridge : IDisposable
{
Task Connect();
void Obstacle();
+1 -1
View File
@@ -2,7 +2,7 @@ using System;
namespace mROA.Abstract
{
public interface IGatewayModule : IDisposable, IInjectableModule
public interface IGatewayModule : IDisposable
{
void Run();
}
+1 -1
View File
@@ -1,6 +1,6 @@
namespace mROA.Abstract
{
public interface IIdentityGenerator : IInjectableModule
public interface IIdentityGenerator
{
int GetNextIdentity();
}
-7
View File
@@ -1,7 +0,0 @@
namespace mROA.Abstract
{
public interface IInjectableModule
{
void Inject(object dependency);
}
}
+1 -1
View File
@@ -3,7 +3,7 @@ using mROA.Implementation;
namespace mROA.Abstract
{
public interface IInstanceRepository : IInjectableModule
public interface IInstanceRepository
{
int ResisterObject<T>(object o, IEndPointContext context);
void ClearObject(ComplexObjectIdentifier id, IEndPointContext context);
+1 -1
View File
@@ -1,6 +1,6 @@
namespace mROA.Abstract
{
public interface IMethodRepository : IInjectableModule
public interface IMethodRepository
{
IMethodInvoker GetMethod(int id);
}
@@ -0,0 +1,7 @@
namespace mROA.Abstract
{
public interface IRealStoreInstanceRepository : IInstanceRepository
{
}
}
+1 -1
View File
@@ -2,7 +2,7 @@ using mROA.Implementation;
namespace mROA.Abstract
{
public interface IRemoteObjectFactory : IInjectableModule
public interface IRemoteObjectFactory
{
T Produce<T>(ComplexObjectIdentifier id, IEndPointContext context);
}
+1 -1
View File
@@ -6,7 +6,7 @@ using mROA.Implementation;
namespace mROA.Abstract
{
public interface IRepresentationModule : IInjectableModule
public interface IRepresentationModule
{
int Id { get; }
IEndPointContext Context { get; }
@@ -1,6 +1,6 @@
namespace mROA.Abstract
{
public interface IRepresentationModuleProducer : IInjectableModule
public interface IRepresentationModuleProducer
{
IRepresentationModule Produce(int id);
}
+1 -1
View File
@@ -2,7 +2,7 @@ using System.Threading.Tasks;
namespace mROA.Abstract
{
public interface IRequestExtractor : IInjectableModule
public interface IRequestExtractor
{
Task StartExtraction();
}
+1 -1
View File
@@ -3,7 +3,7 @@ using System.Threading.Tasks;
namespace mROA.Abstract
{
public interface IUntrustedGateway : IInjectableModule, IDisposable
public interface IUntrustedGateway : IDisposable
{
Task Start();
}
+1 -1
View File
@@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace mROA.Abstract
{
public interface IUntrustedInteractionModule : IInjectableModule, IDisposable
public interface IUntrustedInteractionModule : IDisposable
{
Task Start(IPEndPoint endpoint);
}
@@ -10,9 +10,5 @@ namespace mROA.Implementation.Backend
{
return -++_currentId;
}
public void Inject(object dependency)
{
}
}
}
@@ -1,34 +0,0 @@
using System;
using System.Net;
using System.Reflection;
using mROA.Abstract;
using mROA.Implementation.Bootstrap;
namespace mROA.Implementation.Backend
{
public static class BasicConfigurationExtensions
{
public static void UseNetworkGateway(this FullMixBuilder builder, IPEndPoint endPoint,
Type interactionModuleType, params IInjectableModule[] injectableModules)
{
builder.Modules.Add(new NetworkGatewayModule(endPoint, interactionModuleType, injectableModules));
}
public static void UseBasicExecution(this FullMixBuilder builder)
{
builder.Modules.Add(new BasicExecutionModule());
}
public static void UseCollectableContextRepository(this FullMixBuilder builder, params Assembly[] assemblies)
{
var repo = new InstanceRepository();
repo.FillSingletons(assemblies);
builder.Modules.Add(repo);
}
public static void SetupMethodsRepository(this FullMixBuilder builder, IMethodRepository methodRepository)
{
builder.Modules.Add(methodRepository);
}
}
}
@@ -7,24 +7,15 @@ namespace mROA.Implementation.Backend
{
public class BasicExecutionModule : IExecuteModule
{
private ICancellationRepository? _cancellationRepo;
private IMethodRepository? _methodRepo;
private IContextualSerializationToolKit? _serialization;
private readonly ICancellationRepository _cancellationRepo;
private readonly IMethodRepository _methodRepo;
private readonly IContextualSerializationToolKit _serialization;
public void Inject(object dependency)
public BasicExecutionModule(ICancellationRepository cancellationRepo, IMethodRepository methodRepo, IContextualSerializationToolKit serialization)
{
switch (dependency)
{
case IMethodRepository methodRepo:
_methodRepo = methodRepo;
break;
case ICancellationRepository cancellationRepo:
_cancellationRepo = cancellationRepo;
break;
case IContextualSerializationToolKit serializationToolkit:
_serialization = serializationToolkit;
break;
}
_methodRepo = methodRepo;
_serialization = serialization;
}
public ICommandExecution Execute(ICallRequest command, IInstanceRepository instanceRepository,
@@ -38,7 +29,7 @@ namespace mROA.Implementation.Backend
return CancelExecution(command);
}
var invoker = _methodRepo!.GetMethod(command.CommandId);
var invoker = _methodRepo.GetMethod(command.CommandId);
if (invoker == null)
throw new Exception($"Command {command.CommandId} not found");
@@ -60,10 +51,10 @@ namespace mROA.Implementation.Backend
{
case AsyncMethodInvoker { IsVoid: false } asyncNonVoidMethodInvoker:
return TypedExecuteAsync(asyncNonVoidMethodInvoker, context, castedParams, command,
_cancellationRepo!,
_cancellationRepo,
representationModule, execContext, endPointContext);
case AsyncMethodInvoker asyncMethodInvoker:
return ExecuteAsync(asyncMethodInvoker, context, castedParams, command, _cancellationRepo!,
return ExecuteAsync(asyncMethodInvoker, context, castedParams, command, _cancellationRepo,
representationModule, execContext, endPointContext);
default:
var result = Execute((invoker as MethodInvoker)!, context, castedParams!, command, execContext);
@@ -99,7 +90,7 @@ namespace mROA.Implementation.Backend
object?[] castedParams = new object[invoker.ParameterTypes.Length];
for (var i = 0; i < castedParams.Length; i++)
{
castedParams[i] = _serialization!.Cast(command.Parameters![i], invoker.ParameterTypes[i], context);
castedParams[i] = _serialization.Cast(command.Parameters![i], invoker.ParameterTypes[i], context);
}
return castedParams;
@@ -119,7 +110,7 @@ namespace mROA.Implementation.Backend
private FinalCommandExecution CancelExecution(ICallRequest command)
{
var cts = _cancellationRepo!.GetCancellation(command.Id);
var cts = _cancellationRepo.GetCancellation(command.Id);
if (cts == null)
throw new NullReferenceException("Can't find cancellation for this request");
cts.Cancel();
@@ -237,7 +228,7 @@ namespace mROA.Implementation.Backend
Id = command.Id,
Result = finalResult
};
_cancellationRepo!.FreeCancelation(command.Id);
_cancellationRepo.FreeCancelation(command.Id);
representationModule.PostCallMessage(command.Id, EMessageType.FinishedCommandExecution,
payload, context);
+7 -10
View File
@@ -7,7 +7,12 @@ namespace mROA.Implementation.Backend
public class ConnectionHub : IConnectionHub
{
private readonly Dictionary<int, IChannelInteractionModule> _connections = new();
private IContextualSerializationToolKit? _serializationToolkit;
private IContextualSerializationToolKit _serializationToolkit;
public ConnectionHub(IContextualSerializationToolKit serializationToolkit)
{
_serializationToolkit = serializationToolkit;
}
public void RegisterInteraction(IChannelInteractionModule interaction)
{
@@ -15,9 +20,7 @@ namespace mROA.Implementation.Backend
throw new NullReferenceException("Serialization toolkit is null");
_connections.Add(interaction.ConnectionId, interaction);
var module = new RepresentationModule();
module.Inject(_serializationToolkit);
module.Inject(interaction);
var module = new RepresentationModule(interaction, _serializationToolkit);
OnConnected?.Invoke(module);
}
@@ -29,11 +32,5 @@ namespace mROA.Implementation.Backend
public event ConnectionHandler? OnConnected;
public event DisconnectionHandler? OnDisconnected;
public void Inject(object dependency)
{
if (dependency is IContextualSerializationToolKit serializationToolkit)
_serializationToolkit = serializationToolkit;
}
}
}
@@ -3,41 +3,28 @@ using mROA.Implementation.Frontend;
namespace mROA.Implementation.Backend
{
public class HubRequestExtractor : IInjectableModule
public class HubRequestExtractor
{
private IConnectionHub? _hub;
private IConnectionHub _hub;
private IInstanceRepository? _contextRepository;
private IInstanceRepository? _remoteContextRepository;
private IMethodRepository? _methodRepository;
private IContextualSerializationToolKit? _serializationToolkit;
private IExecuteModule? _executeModule;
private IRealStoreInstanceRepository _contextRepository;
private IInstanceRepository _remoteContextRepository;
private IMethodRepository _methodRepository;
private IContextualSerializationToolKit _serializationToolkit;
private IExecuteModule _executeModule;
public void Inject(object dependency)
public HubRequestExtractor(IConnectionHub hub, IRealStoreInstanceRepository contextRepository,
RemoteInstanceRepository remoteContextRepository, IMethodRepository methodRepository,
IContextualSerializationToolKit serializationToolkit, IExecuteModule executeModule)
{
switch (dependency)
{
case IConnectionHub connectionHub:
_hub = connectionHub;
_hub = hub;
_hub.OnConnected += HubOnOnConnected;
break;
case MultiClientInstanceRepository:
case InstanceRepository:
_contextRepository = dependency as IInstanceRepository;
break;
case RemoteInstanceRepository remoteContextRepository:
_contextRepository = contextRepository;
_remoteContextRepository = remoteContextRepository;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case IContextualSerializationToolKit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
}
}
private void HubOnOnConnected(IRepresentationModule interaction)
@@ -54,20 +41,15 @@ namespace mROA.Implementation.Backend
private IRequestExtractor CreateExtractor(IRepresentationModule interaction)
{
var extractor = new RequestExtractor();
var extractor = new RequestExtractor(_executeModule, _methodRepository, interaction, _serializationToolkit, interaction.Context);
var context = interaction.Context;
extractor.Inject(interaction);
if (_contextRepository is IContextRepositoryHub contextHub)
context.RealRepository = contextHub.GetRepository(interaction.Id);
else
context.RealRepository = _contextRepository!;
context.RealRepository = _contextRepository;
context.RemoteRepository = _remoteContextRepository!;
context.RemoteRepository = _remoteContextRepository;
extractor.Inject(context);
extractor.Inject(_methodRepository);
extractor.Inject(_serializationToolkit);
extractor.Inject(_executeModule);
return extractor;
}
}
@@ -7,17 +7,18 @@ using mROA.Implementation.Attributes;
namespace mROA.Implementation.Backend
{
public class InstanceRepository : IInstanceRepository
public class InstanceRepository : IRealStoreInstanceRepository
{
public static object[] EventBinders = { };
private IRepresentationModuleProducer? _representationModuleProducer;
private IRepresentationModuleProducer _representationModuleProducer;
private Dictionary<int, object?> _singletons = new();
private readonly IStorage<object> _storage;
public InstanceRepository()
public InstanceRepository(IRepresentationModuleProducer representationModuleProducer)
{
_representationModuleProducer = representationModuleProducer;
_storage = new ExtensibleStorage<object>();
}
@@ -34,7 +35,7 @@ namespace mROA.Implementation.Backend
var binders = EventBinders.Where(i => generic.Any(g => g.IsAssignableFrom(i.GetType())));
foreach (var binder in binders)
((IEventBinder)binder).BindEvents(o, context, _representationModuleProducer!, last);
((IEventBinder)binder).BindEvents(o, context, _representationModuleProducer, last);
return last;
}
@@ -74,14 +75,6 @@ namespace mROA.Implementation.Backend
return index == -1 ? ResisterObject<T>(o, context) : index;
}
public void Inject(object dependency)
{
if (dependency is IRepresentationModuleProducer moduleProducer)
{
_representationModuleProducer = moduleProducer;
}
}
public void FillSingletons(params Assembly[] assembly)
{
var types = assembly.SelectMany(x => x.GetTypes()).Where(type =>
@@ -4,7 +4,7 @@ using mROA.Abstract;
namespace mROA.Implementation.Backend
{
public class MultiClientInstanceRepository : IInstanceRepository, IContextRepositoryHub
public class MultiClientInstanceRepository : IRealStoreInstanceRepository, IContextRepositoryHub
{
private readonly Func<int, IInstanceRepository> _produceRepository;
private readonly Dictionary<int, IInstanceRepository> _repositories = new();
@@ -14,10 +14,6 @@ namespace mROA.Implementation.Backend
_produceRepository = produceRepository;
}
public void Inject(object dependency)
{
}
public int HostId { get; set; }
public int ResisterObject<T>(object o, IEndPointContext context)
@@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using mROA.Abstract;
namespace mROA.Implementation.Backend
{
public class MultiClientOwnershipRepository : IOwnershipRepository
{
private Dictionary<int, int> _ownerships = new();
public int GetOwnershipId()
{
return _ownerships.GetValueOrDefault(Environment.CurrentManagedThreadId, 0);
}
public int GetHostOwnershipId() => 0;
public void RegisterOwnership(int ownershipId)
{
_ownerships.TryAdd(Environment.CurrentManagedThreadId, ownershipId);
}
public void FreeOwnership()
{
_ownerships.Remove(Environment.CurrentManagedThreadId);
}
}
}
@@ -4,26 +4,26 @@ using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using mROA.Abstract;
namespace mROA.Implementation.Backend
{
public class NetworkGatewayModule : IGatewayModule
{
private readonly IInjectableModule[]? _injectableModules;
private readonly Type? _interactionModuleType;
private readonly IServiceProvider _serviceProvider;
private readonly TcpListener _tcpListener;
private IConnectionHub? _hub;
private IContextualSerializationToolKit? _serialization;
private Dictionary<int, CancellationTokenSource> _extractorsCTS = new();
private ICallIndexProvider _callIndexProvider;
public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType,
IInjectableModule[] injectableModules)
private readonly IContextualSerializationToolKit _serialization;
private readonly Dictionary<int, CancellationTokenSource> _extractorsCTS = new();
private ICallIndexProvider? _callIndexProvider;
private readonly IIdentityGenerator _identityGenerator;
public NetworkGatewayModule(IOptions<GatewayOptions> options, IServiceProvider service, IIdentityGenerator identityGenerator, IContextualSerializationToolKit serialization)
{
_tcpListener = new(endpoint);
_interactionModuleType = interactionModuleType;
_injectableModules = injectableModules;
_tcpListener = new(options.Value.Endpoint);
_serviceProvider = service;
_identityGenerator = identityGenerator;
_serialization = serialization;
}
public void Run()
@@ -40,40 +40,15 @@ namespace mROA.Implementation.Backend
_tcpListener.Stop();
}
public void Inject(object dependency)
{
switch (dependency)
{
case IConnectionHub interactionModule:
_hub = interactionModule;
break;
case IContextualSerializationToolKit serializationToolkit:
_serialization = serializationToolkit;
break;
case ICallIndexProvider callIndexProvider:
_callIndexProvider = callIndexProvider;
break;
}
}
private async Task HandleIncomingConnections()
{
ThrowIfNotInjected();
while (true)
{
var client = await _tcpListener.AcceptTcpClientAsync();
Console.WriteLine($"Client connected from {client.Client.RemoteEndPoint}");
var interaction = Activator.CreateInstance(_interactionModuleType!) as IChannelInteractionModule;
var interaction = new ChannelInteractionModule(_serialization, _identityGenerator);
foreach (var injectableModule in _injectableModules!)
interaction!.Inject(injectableModule);
interaction!.Inject(_serialization);
//TODO сделать контекст
var context = new EndPointContext();
var context = new EndPointContext(null, null);
context.CallIndexProvider = _callIndexProvider;
var streamExtractor =
new ChannelInteractionModule.StreamExtractor(client.GetStream(), _serialization, context);
@@ -91,7 +66,7 @@ namespace mROA.Implementation.Backend
case EMessageType.ClientConnect:
context.HostId = 0;
context.OwnerId = -interaction.ConnectionId;
interaction.Inject(context);
interaction.Context = context;
Task.Run(async () => await streamExtractor.LoopedReceive(cts.Token));
_ = streamExtractor.SendFromChannel(interaction.TrustedPostChanel, cts.Token);
interaction.PostMessageAsync(new NetworkMessageHeader(_serialization!,
@@ -126,19 +101,11 @@ namespace mROA.Implementation.Backend
}
}
}
private void ThrowIfNotInjected()
{
if (_hub is null)
throw new NullReferenceException("Hub module is null");
if (_tcpListener == null)
throw new NullReferenceException("TcpListener is null");
if (_injectableModules is null)
throw new NullReferenceException("InjectableModules is null");
if (_interactionModuleType is null)
throw new NullReferenceException("InteractionModuleType is null");
if (_serialization is null)
throw new NullReferenceException("Serialization is null");
}
public class GatewayOptions
{
public IPEndPoint Endpoint { get; set; }
public Type InteractionModuleType { get; set; }
}
}
+4 -17
View File
@@ -18,28 +18,15 @@ namespace mROA.Implementation.Backend
private IContextualSerializationToolKit _serializationToolkit;
private IEndPointContext _context;
public UdpGateway(IPEndPoint listeningEndpoint)
public UdpGateway(IPEndPoint listeningEndpoint, IConnectionHub hub, IContextualSerializationToolKit serializationToolkit, IEndPointContext context)
{
_hub = hub;
_serializationToolkit = serializationToolkit;
_context = context;
_client = new UdpClient(listeningEndpoint);
}
public void Inject(object dependency)
{
switch (dependency)
{
case IConnectionHub hub:
_hub = hub;
break;
case IContextualSerializationToolKit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
case IEndPointContext context:
_context = context;
break;
}
}
public void Dispose()
{
_tokenSource.Cancel();
@@ -1,36 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using mROA.Abstract;
namespace mROA.Implementation.Bootstrap
{
public class FullMixBuilder
{
public List<IInjectableModule> Modules { get; } = new();
public void Build()
{
foreach (var module in Modules)
foreach (var injection in Modules)
module.Inject(injection);
}
public T GetModule<T>()
{
return Modules.OfType<T>().FirstOrDefault();
}
public bool TryGetModule<T>(out IInjectableModule module) where T : IInjectableModule
{
var mod = Modules.OfType<T>().FirstOrDefault();
if (mod is null)
{
module = default;
return false;
}
module = mod;
return true;
}
}
}
@@ -24,9 +24,5 @@ namespace mROA.Implementation
{
_cancellations.Remove(id, out _);
}
public void Inject(object dependency)
{
}
}
}
@@ -15,14 +15,17 @@ namespace mROA.Implementation
private readonly ChannelWriter<NetworkMessageHeader> _untrustedWriter;
private readonly Channel<NetworkMessageHeader> _outputTrustedChannel;
private readonly Channel<NetworkMessageHeader> _outputUntrustedChannel;
private IContextualSerializationToolKit? _serialization;
private IContextualSerializationToolKit _serialization;
private bool _isConnected = true;
private bool _isActive = true;
private TaskCompletionSource<Stream> _reconnection;
private IEndPointContext? _context;
public ChannelInteractionModule()
public ChannelInteractionModule(IContextualSerializationToolKit serialization,
IIdentityGenerator identityGenerator)
{
_serialization = serialization;
ConnectionId = identityGenerator.GetNextIdentity();
ReceiveChanel = Channel.CreateUnbounded<NetworkMessageHeader>(new UnboundedChannelOptions
{
SingleReader = false,
@@ -46,29 +49,13 @@ namespace mROA.Implementation
public int ConnectionId { get; set; }
public IEndPointContext Context => _context;
public IEndPointContext Context { get; set; }
public Channel<NetworkMessageHeader> ReceiveChanel { get; }
public ChannelReader<NetworkMessageHeader> TrustedPostChanel => _outputTrustedChannel.Reader;
public ChannelReader<NetworkMessageHeader> UntrustedPostChanel => _outputUntrustedChannel.Reader;
public Func<bool> IsConnected { get; set; } = () => false;
public void Inject(object dependency)
{
switch (dependency)
{
case IContextualSerializationToolKit toolkit:
_serialization = toolkit;
break;
case IIdentityGenerator identityGenerator:
ConnectionId = identityGenerator.GetNextIdentity();
break;
case IEndPointContext endpointContext:
_context = endpointContext;
break;
}
}
public ValueTask<NetworkMessageHeader> GetNextMessageReceiving(bool infinite = true)
{
return _receiveReader.ReadAsync();
@@ -122,7 +109,7 @@ namespace mROA.Implementation
if (sendRecovery)
{
await PostMessageAsync(
new NetworkMessageHeader(_serialization!, new ClientRecovery(Math.Abs(ConnectionId)), _context));
new NetworkMessageHeader(_serialization, new ClientRecovery(Math.Abs(ConnectionId)), Context));
await ReceiveChanel.Reader.ReadAsync();
}
else
@@ -7,10 +7,6 @@ namespace mROA.Implementation
{
private List<IMethodInvoker> _methods = new();
public void Inject(object dependency)
{
}
public void AppendInvokers(IEnumerable<IMethodInvoker> methodInvokers)
{
_methods.AddRange(methodInvokers);
@@ -1,6 +1,5 @@
using System;
using mROA.Abstract;
using mROA.Implementation.Bootstrap;
using mROA.Implementation.Frontend;
namespace mROA.Implementation.CommandExecution
@@ -5,37 +5,25 @@ namespace mROA.Implementation
{
public class CreativeRepresentationModuleProducer : IRepresentationModuleProducer
{
private Type _reprModuleType;
private IInjectableModule[] _creationModules;
private IConnectionHub? _hub;
public CreativeRepresentationModuleProducer(IInjectableModule[] creationModules, Type reprModuleType)
private IServiceProvider _creationModules;
private IConnectionHub _hub;
private IContextualSerializationToolKit _serialization;
public CreativeRepresentationModuleProducer(IServiceProvider creationModules, IConnectionHub hub, IContextualSerializationToolKit serialization)
{
_creationModules = creationModules;
_reprModuleType = reprModuleType;
_hub = hub;
_serialization = serialization;
}
public void Inject(object dependency)
{
if (dependency is IConnectionHub interactionModule)
_hub = interactionModule;
}
public IRepresentationModule Produce(int id)
{
if (_hub == null)
throw new NullReferenceException("Interaction module is null");
var produced =
Activator.CreateInstance(_reprModuleType) as IRepresentationModule ??
throw new Exception("Bad serialization module type");
foreach (var creationModule in _creationModules)
produced.Inject(creationModule);
var interaction = _hub.GetInteraction(id);
produced.Inject(interaction);
var produced = new RepresentationModule(interaction, _serialization);
return produced;
}
+10 -15
View File
@@ -1,10 +1,19 @@
using mROA.Abstract;
using mROA.Implementation.Backend;
namespace mROA.Implementation
{
public class EndPointContext : IEndPointContext
{
public EndPointContext()
{
}
public EndPointContext(IInstanceRepository realRepository, IInstanceRepository remoteRepository)
{
RealRepository = realRepository;
RemoteRepository = remoteRepository;
}
public IInstanceRepository RealRepository { get; set; }
public IInstanceRepository RemoteRepository { get; set; }
public ICallIndexProvider CallIndexProvider { get; set; }
@@ -12,19 +21,5 @@ namespace mROA.Implementation
public int HostId { get; set; }
public int OwnerId { get; set; }
public void Inject(object dependency)
{
switch (dependency)
{
case RemoteInstanceRepository remoteRepository:
RemoteRepository = remoteRepository;
break;
case InstanceRepository realRepository:
RealRepository = realRepository;
break;
}
}
}
}
@@ -13,33 +13,19 @@ namespace mROA.Implementation.Frontend
private readonly IPEndPoint _serverEndPoint;
private TcpClient _tcpClient = new();
private IChannelInteractionModule? _interactionModule;
private IContextualSerializationToolKit? _serialization;
private ChannelInteractionModule.StreamExtractor _currentExtractor;
private IContextualSerializationToolKit _serialization;
private ChannelInteractionModule.StreamExtractor? _currentExtractor;
private CancellationTokenSource _rawExtractorCancellation;
private IEndPointContext _context;
public NetworkFrontendBridge(IPEndPoint serverEndPoint)
public NetworkFrontendBridge(IPEndPoint serverEndPoint, IEndPointContext context, IContextualSerializationToolKit serialization)
{
_serverEndPoint = serverEndPoint;
_context = context;
_serialization = serialization;
_rawExtractorCancellation = new CancellationTokenSource();
}
public void Inject(object dependency)
{
switch (dependency)
{
case ChannelInteractionModule interactionModule:
_interactionModule = interactionModule;
break;
case IContextualSerializationToolKit toolkit:
_serialization = toolkit;
break;
case IEndPointContext endPointContext:
_context = endPointContext;
break;
}
}
public async Task Connect()
{
if (_interactionModule is null)
@@ -77,7 +63,7 @@ namespace mROA.Implementation.Frontend
private void PrepareExtractor()
{
_currentExtractor =
new ChannelInteractionModule.StreamExtractor(_tcpClient.GetStream(), _serialization!, _context);
new ChannelInteractionModule.StreamExtractor(_tcpClient.GetStream(), _serialization, _context);
_ = _currentExtractor.SendFromChannel(_interactionModule!.TrustedPostChanel,
_rawExtractorCancellation.Token);
@@ -109,7 +95,7 @@ namespace mROA.Implementation.Frontend
public void Disconnect()
{
_ = _interactionModule!.PostMessageAsync(new NetworkMessageHeader(_serialization!, new ClientDisconnect(),
_ = _interactionModule!.PostMessageAsync(new NetworkMessageHeader(_serialization, new ClientDisconnect(),
_context));
_interactionModule.Dispose();
_tcpClient.Dispose();
@@ -9,34 +9,21 @@ namespace mROA.Implementation.Frontend
{
public class RequestExtractor : IRequestExtractor
{
private IExecuteModule? _executeModule;
private IExecuteModule _executeModule;
private IMethodRepository? _methodRepository;
private IMethodRepository _methodRepository;
private IRepresentationModule? _representationModule;
private IContextualSerializationToolKit? _serializationToolkit;
private IRepresentationModule _representationModule;
private IContextualSerializationToolKit _serializationToolkit;
private IEndPointContext _context;
public void Inject(object dependency)
public RequestExtractor(IExecuteModule executeModule, IMethodRepository methodRepository, IRepresentationModule representationModule, IContextualSerializationToolKit serializationToolkit, IEndPointContext context)
{
switch (dependency)
{
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case IRepresentationModule representationModule:
_representationModule = representationModule;
break;
case IContextualSerializationToolKit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
case IEndPointContext remoteContext:
_context = remoteContext;
break;
}
_context = context;
}
public async Task StartExtraction()
@@ -45,7 +32,7 @@ namespace mROA.Implementation.Frontend
var streamTokenSource = new CancellationTokenSource();
var query = _representationModule!.GetStream(m =>
var query = _representationModule.GetStream(m =>
m.MessageType is EMessageType.CallRequest or EMessageType.CancelRequest
or EMessageType.EventRequest or EMessageType.ClientDisconnect, _context,
streamTokenSource.Token,
@@ -90,12 +77,12 @@ namespace mROA.Implementation.Frontend
private void HandleCancelRequest(CancelRequest req)
{
_executeModule!.Execute(req, _context.RealRepository, _representationModule!, _context);
_executeModule.Execute(req, _context.RealRepository, _representationModule, _context);
}
private void HandleCallRequest(DefaultCallRequest request)
{
var result = _executeModule!.Execute(request, _context.RealRepository, _representationModule!, _context);
var result = _executeModule.Execute(request, _context.RealRepository, _representationModule, _context);
var resultType = result.MessageType;
@@ -104,12 +91,12 @@ namespace mROA.Implementation.Frontend
return;
}
_representationModule!.PostCallMessage(request.Id, resultType, result, _context);
_representationModule.PostCallMessage(request.Id, resultType, result, _context);
}
private void HandleEventRequest(DefaultCallRequest request)
{
_executeModule!.Execute(request, _context.RemoteRepository, _representationModule!, _context);
_executeModule.Execute(request, _context.RemoteRepository, _representationModule, _context);
}
}
}
@@ -9,10 +9,17 @@ namespace mROA.Implementation.Frontend
{
public class UdpUntrustedInteraction : IUntrustedInteractionModule
{
private IContextualSerializationToolKit _serializationToolkit;
private IChannelInteractionModule _channelInteractionModule;
private CancellationTokenSource _tokenSource = new();
private IEndPointContext _context;
private readonly IContextualSerializationToolKit _serializationToolkit;
private readonly IChannelInteractionModule _channelInteractionModule;
private readonly CancellationTokenSource _tokenSource = new();
private readonly IEndPointContext _context;
public UdpUntrustedInteraction(IContextualSerializationToolKit serializationToolkit, IChannelInteractionModule channelInteractionModule, IEndPointContext context)
{
_serializationToolkit = serializationToolkit;
_channelInteractionModule = channelInteractionModule;
_context = context;
}
public void Dispose()
{
@@ -65,21 +72,5 @@ namespace mROA.Implementation.Frontend
await udpClient.SendAsync(serialized, serialized.Length);
}
}
public void Inject(object dependency)
{
switch (dependency)
{
case IChannelInteractionModule channelModule:
_channelInteractionModule = channelModule;
break;
case IContextualSerializationToolKit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
case IEndPointContext endPointContext:
_context = endPointContext;
break;
}
}
}
}
@@ -10,7 +10,14 @@ namespace mROA.Implementation
private List<RemoteObjectBase> _producedProxys = new();
private ICallIndexProvider _callIndexProvider;
private IRepresentationModuleProducer? _representationProducer;
private IRepresentationModuleProducer _representationProducer;
public RemoteInstanceRepository(ICallIndexProvider callIndexProvider, IRepresentationModuleProducer representationProducer, int hostId)
{
_callIndexProvider = callIndexProvider;
_representationProducer = representationProducer;
HostId = hostId;
}
public int HostId { get; set; }
@@ -76,18 +83,5 @@ namespace mROA.Implementation
throw new NotSupportedException();
}
public void Inject(object dependency)
{
switch (dependency)
{
case IRepresentationModuleProducer serialisationModule:
_representationProducer = serialisationModule;
break;
case ICallIndexProvider callIndexProvider:
_callIndexProvider = callIndexProvider;
break;
}
}
}
}
+5 -12
View File
@@ -12,20 +12,13 @@ namespace mROA.Implementation
{
public class RepresentationModule : IRepresentationModule
{
private IChannelInteractionModule? _interaction;
private IContextualSerializationToolKit? _serialization;
private IChannelInteractionModule _interaction;
private IContextualSerializationToolKit _serialization;
public void Inject(object dependency)
public RepresentationModule(IChannelInteractionModule interaction, IContextualSerializationToolKit serialization)
{
switch (dependency)
{
case IContextualSerializationToolKit toolkit:
_serialization = toolkit;
break;
case IChannelInteractionModule interactionModule:
_interaction = interactionModule;
break;
}
_interaction = interaction;
_serialization = serialization;
}
@@ -5,7 +5,12 @@ namespace mROA.Implementation
{
public class StaticRepresentationModuleProducer : IRepresentationModuleProducer
{
private IRepresentationModule? _representationModule;
private readonly IRepresentationModule _representationModule;
public StaticRepresentationModuleProducer(IRepresentationModule representationModule)
{
_representationModule = representationModule;
}
public IRepresentationModule Produce(int ownership)
{
@@ -13,11 +18,5 @@ namespace mROA.Implementation
throw new NullReferenceException("The representation module is not initialized.");
return _representationModule;
}
public void Inject(object dependency)
{
if (dependency is IRepresentationModule serialisationModule)
_representationModule = serialisationModule;
}
}
}
+2
View File
@@ -26,6 +26,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.5"/>
<PackageReference Include="System.Threading.Channels" Version="9.0.5"/>
</ItemGroup>