что то неожиданно сломалось после рефакторинга

This commit is contained in:
2025-02-07 16:53:12 +03:00
parent 33ca84fb0d
commit 4a95cd84c1
34 changed files with 154 additions and 185 deletions
+1
View File
@@ -1,6 +1,7 @@
using Example.Backend;
using Example.Shared;
using mROA.Implementation;
using mROA.Implementation.Attributes;
namespace Example.Backend;
+4 -1
View File
@@ -1,7 +1,9 @@
using System.Net;
using Example.Backend;
using mROA.Abstract;
using mROA.Codegen;
using mROA.Implementation;
using mROA.Implementation.Backend;
using mROA.Implementation.Bootstrap;
@@ -14,6 +16,7 @@ bootstrap.UseCollectableContextRepository(typeof(PrinterFactory).Assembly);
bootstrap.SetupMethodsRepository(new CoCodegenMethodRepository());
bootstrap.Build();
var gateway = bootstrap.GetModule<IGatewayModule>();
var gateway = bootstrap.GetModule<IGatewayModule>() ;
gateway.Run();
+4 -1
View File
@@ -4,8 +4,9 @@
using System.Net;
using System.Text;
using mROA.Codegen;
using mROA.Implementation;
using mROA.Implementation.Bootstrap;
using mROA.Implementation.Frontend;
var mixer = new FullMixBuilder();
@@ -15,6 +16,8 @@ mixer.Modules.Add(new StreamBasedFrontendInteractionModule());
mixer.Modules.Add(new NetworkFrontendBridge(new IPEndPoint(IPAddress.Loopback, 4567)));
mixer.Build();
mixer.GetModule<NetworkFrontendBridge>().Connect();
var context = mixer.GetModule<FrontendContextRepository>();
var factory = context.GetSingleObject(typeof(Example.Shared.IPrinterFactory)) as Example.Shared.IPrinterFactory;
+2 -4
View File
@@ -7,10 +7,8 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\mROA.Codegen\mROA.Codegen.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"/>
<ProjectReference Include="..\mROA\mROA.csproj" />
<ProjectReference Include="..\mROA.Codegen\mROA.Codegen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
<ProjectReference Include="..\mROA\mROA.csproj"/>
</ItemGroup>
</Project>
+1
View File
@@ -1,4 +1,5 @@
using mROA.Implementation;
using mROA.Implementation.Attributes;
namespace Example.Shared;
+2
View File
@@ -1,4 +1,5 @@
using mROA.Implementation;
using mROA.Implementation.Attributes;
namespace Example.Shared;
@@ -7,4 +8,5 @@ public interface IPrinter
{
string GetName();
Task<TransmittedSharedObject<IPage>> Print(string text, CancellationToken cancellationToken);
}
+1
View File
@@ -1,4 +1,5 @@
using mROA.Implementation;
using mROA.Implementation.Attributes;
namespace Example.Shared;
@@ -66,7 +66,7 @@ namespace {Namespace}
string attributeName = attributeSymbol.ContainingType.ToDisplayString();
// Check the full name of the [Report] attribute.
if (attributeName == "mROA.Implementation.SharedObjectInterfaceAttribute")
if (attributeName == "mROA.Implementation.Attributes.SharedObjectInterfaceAttribute")
return (classDeclarationSyntax, true);
}
+1 -1
View File
@@ -1,4 +1,4 @@
namespace mROA;
namespace mROA.Abstract;
public interface ICommandExecution
{
+2 -5
View File
@@ -1,13 +1,10 @@
using mROA.Abstract;
using mROA.Implementation;
namespace mROA;
namespace mROA.Abstract;
public interface IContextRepository : IInjectableModule
{
int ResisterObject(object o);
void ClearObject(int id);
object? GetObject(int id);
object GetObject(int id);
T? GetObject<T>(int id);
object GetSingleObject(Type type);
int GetObjectIndex(object o);
+1 -2
View File
@@ -1,7 +1,6 @@
using mROA.Abstract;
using mROA.Implementation;
namespace mROA;
namespace mROA.Abstract;
public interface IExecuteModule : IInjectableModule
{
+1 -3
View File
@@ -1,6 +1,4 @@
using mROA.Abstract;
namespace mROA.Implementation;
namespace mROA.Abstract;
public interface IGatewayModule : IDisposable, IInjectableModule
{
+1 -3
View File
@@ -1,6 +1,4 @@
using mROA.Abstract;
namespace mROA;
namespace mROA.Abstract;
public interface IInteractionModule : IInjectableModule
{
+1 -2
View File
@@ -1,7 +1,6 @@
using System.Reflection;
using mROA.Abstract;
namespace mROA;
namespace mROA.Abstract;
public interface IMethodRepository : IInjectableModule
{
+1 -1
View File
@@ -1,4 +1,4 @@
namespace mROA.Implementation;
namespace mROA.Abstract;
public interface IRemoteObject
{
+1 -2
View File
@@ -1,7 +1,6 @@
using mROA.Abstract;
using mROA.Implementation;
namespace mROA;
namespace mROA.Abstract;
public interface ISerialisationModule : IInjectableModule
{
@@ -1,3 +1,3 @@
namespace mROA.Implementation;
namespace mROA.Implementation.Attributes;
public class SharedObjectInterfaceAttribute : Attribute;
@@ -1,3 +1,3 @@
namespace mROA.Implementation;
namespace mROA.Implementation.Attributes;
public class SharedObjectSingletonAttribute : Attribute;
@@ -1,8 +1,9 @@
using System.Net;
using System.Reflection;
using mROA.Abstract;
using mROA.Implementation.Bootstrap;
namespace mROA.Implementation;
namespace mROA.Implementation.Backend;
public static class BasicConfigurationExtensions
{
@@ -1,32 +1,31 @@
using System.Reflection;
using mROA.Abstract;
namespace mROA.Implementation;
namespace mROA.Implementation.Backend;
public class BasicExecutionModule : IExecuteModule
{
private IMethodRepository _methodRepo;
private ISerialisationModule _serialisationModule;
private IContextRepository _contextRepo;
private IMethodRepository? _methodRepo;
private IContextRepository? _contextRepo;
public void Inject<T>(T dependency)
{
if (dependency is IMethodRepository methodRepo)
_methodRepo = methodRepo;
if (dependency is ISerialisationModule serialisationModule)
_serialisationModule = serialisationModule;
if (dependency is IContextRepository contextRepo)
_contextRepo = contextRepo;
}
public ICommandExecution Execute(ICallRequest command)
{
var currentCommand = _methodRepo.GetMethod(command.CommandId);
var currentCommand = _methodRepo!.GetMethod(command.CommandId);
if (currentCommand == null)
throw new Exception($"Command {command.CommandId} not found");
var context = command.ObjectId != -1
? _contextRepo.GetObject(command.ObjectId)
: _contextRepo.GetSingleObject(currentCommand.DeclaringType!);
? _contextRepo!.GetObject(command.ObjectId)
: _contextRepo!.GetSingleObject(currentCommand.DeclaringType!);
var parameter = command.Parameter;
if (currentCommand.ReturnType.BaseType == typeof(Task) &&
@@ -57,7 +56,7 @@ public class BasicExecutionModule : IExecuteModule
return new ExceptionCommandExecution
{
CallRequestId = command.CallRequestId, CommandId = command.CommandId,
Exeption = e.ToString()
Exception = e.ToString()
};
}
}
@@ -82,7 +81,7 @@ public class BasicExecutionModule : IExecuteModule
return new ExceptionCommandExecution
{
CallRequestId = command.CallRequestId, CommandId = command.CommandId,
Exeption = e.ToString()
Exception = e.ToString()
};
}
}
@@ -105,7 +104,7 @@ public class BasicExecutionModule : IExecuteModule
CallRequestId = command.CallRequestId,
Result = finalResult,
CommandId = command.CommandId,
Type = finalResult.GetType()
Type = finalResult?.GetType()
};
}
catch (Exception e)
@@ -113,7 +112,7 @@ public class BasicExecutionModule : IExecuteModule
return new ExceptionCommandExecution
{
CallRequestId = command.CallRequestId, CommandId = command.CommandId,
Exeption = e.ToString()
Exception = e.ToString()
};
}
}
@@ -1,12 +1,14 @@
using System.Collections.Frozen;
using System.Reflection;
using mROA.Abstract;
using mROA.Implementation.Attributes;
namespace mROA.Implementation;
namespace mROA.Implementation.Backend;
public class ContextRepository : IContextRepository
{
private FrozenDictionary<int, object?> _singletons;
private object[] _storage;
private FrozenDictionary<int, object?>? _singletons;
private object?[] _storage = new object[StartupSize];
private Task<int> _lastIndexFinder = Task.FromResult(0);
@@ -14,11 +16,6 @@ public class ContextRepository : IContextRepository
const int GrowSize = 128;
public ContextRepository()
{
_storage = new object[StartupSize];
}
public void FillSingletons(params Assembly[] assembly)
{
var types = assembly.SelectMany(x => x.GetTypes()).Where(type =>
@@ -39,7 +36,7 @@ public class ContextRepository : IContextRepository
_storage[_lastIndexFinder.Result] = o;
var last = _lastIndexFinder.Result;
_lastIndexFinder = FindLastIndex();
_lastIndexFinder = Task.Run(FindLastIndex);
return last;
}
@@ -50,30 +47,28 @@ public class ContextRepository : IContextRepository
_lastIndexFinder = Task.FromResult(id);
}
public object? GetObject(int id)
public object GetObject(int id)
{
return id == -1 || _storage.Length <= id ? null : _storage[id];
return (id == -1 || _storage.Length <= id ? null : _storage[id]) ?? throw new NullReferenceException();
}
public T GetObject<T>(int id)
{
return id == -1 || _storage.Length <= id ? throw new NullReferenceException("Cannot find that object. It is null"): (T)_storage[id];
return id == -1 || _storage.Length <= id ? throw new NullReferenceException("Cannot find that object. It is null"): (T)_storage[id]!;
}
public object GetSingleObject(Type type)
{
return _singletons.GetValueOrDefault(type.GetHashCode()) ?? throw new ArgumentException("Unregistered singleton type");
return _singletons!.GetValueOrDefault(type.GetHashCode()) ?? throw new ArgumentException("Unregistered singleton type");
}
public int GetObjectIndex(object o)
{
var index = Array.IndexOf(_storage, o);
if (index == -1)
return ResisterObject(o);
return index;
return index == -1 ? ResisterObject(o) : index;
}
private async Task<int> FindLastIndex()
private int FindLastIndex()
{
for (int i = 0; i < _storage.Length; i++)
{
@@ -83,6 +78,7 @@ public class ContextRepository : IContextRepository
var nextStorage = new object[_storage.Length + GrowSize];
Array.Copy(_storage, nextStorage, _storage.Length);
_storage = nextStorage;
return _storage.Length;
}
public void Inject<T>(T dependency)
@@ -1,27 +1,26 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using mROA.Implementation.Bootstrap;
using mROA.Abstract;
namespace mROA.Implementation;
namespace mROA.Implementation.Backend;
public class JsonSerialisationModule : ISerialisationModule
{
private IInteractionModule _dataSource;
private IExecuteModule _executeModule;
private IMethodRepository _methodRepository;
private IInteractionModule? _dataSource;
private IExecuteModule? _executeModule;
private IMethodRepository? _methodRepository;
public void HandleIncomingRequest(int clientId, byte[] command)
{
DefaultCallRequest request = JsonSerializer.Deserialize<DefaultCallRequest>(command);
DefaultCallRequest request = JsonSerializer.Deserialize<DefaultCallRequest>(command)!;
if (request.Parameter is not null)
{
var parameter = _methodRepository.GetMethod(request.CommandId).GetParameters().First().ParameterType;
var parameter = _methodRepository!.GetMethod(request.CommandId).GetParameters().First().ParameterType;
request.Parameter = ((JsonElement)request.Parameter).Deserialize(parameter);
}
var response = _executeModule.Execute(request);
var response = _executeModule!.Execute(request);
response.ClientId = clientId;
PostResponse(response);
}
@@ -47,7 +46,7 @@ public class JsonSerialisationModule : ISerialisationModule
// }
var binary = Encoding.UTF8.GetBytes(texted);
_dataSource.SendTo(call.ClientId, binary);
_dataSource!.SendTo(call.ClientId, binary);
}
public void Inject<T>(T dependency)
@@ -1,17 +1,14 @@
using System.Net;
using System.Net.Sockets;
using mROA.Abstract;
namespace mROA.Implementation;
namespace mROA.Implementation.Backend;
public class NetworkGatewayModule : IGatewayModule
public class NetworkGatewayModule(IPEndPoint endpoint) : IGatewayModule
{
private TcpListener _tcpListener;
private IInteractionModule _interactionModule;
private readonly TcpListener _tcpListener = new(endpoint);
private IInteractionModule? _interactionModule;
public NetworkGatewayModule(IPEndPoint endpoint)
{
_tcpListener = new TcpListener(endpoint);
}
public void Run()
{
@@ -41,6 +38,8 @@ public class NetworkGatewayModule : IGatewayModule
private void HandleIncomingConnections()
{
if (_interactionModule is null)
throw new NullReferenceException("Interaction module is null");
while (true)
{
var client = _tcpListener.AcceptTcpClient();
@@ -1,15 +1,17 @@
namespace mROA.Implementation;
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class StreamBasedInteractionModule : IInteractionModule
{
private Dictionary<int, Stream> _streams = new();
private Action<int, byte[]> _handler;
private readonly Dictionary<int, Stream> _streams = new();
private Action<int, byte[]>? _handler;
public void RegisterSourse(Stream stream)
{
var id = Random.Shared.Next();
_streams.Add(id, stream);
ListenTo((id, stream), _handler);
_ = ListenTo((id, stream), _handler!);
}
public void SendTo(int clientId, byte[] message)
@@ -34,7 +36,7 @@ public class StreamBasedInteractionModule : IInteractionModule
await client.stream.ReadExactlyAsync(buffer, 0, 2);
var len = BitConverter.ToUInt16(buffer, 0);
await client.stream.ReadExactlyAsync(buffer, 0, len);
Task.Run(() => action(client.id, buffer[..len]));
_ = Task.Run(() => action(client.id, buffer[..len]));
}
}
catch (Exception)
@@ -2,14 +2,14 @@ using mROA.Abstract;
namespace mROA.Implementation.Bootstrap;
public interface ImRoaBuilder
public interface IRoaBuilder
{
void Build();
}
public class FullMixBuilder : ImRoaBuilder
public class FullMixBuilder : IRoaBuilder
{
public List<IInjectableModule> Modules { get; private set; } = new();
public List<IInjectableModule> Modules { get; } = new();
public void Build()
{
foreach (var module in Modules)
@@ -17,7 +17,7 @@ public class FullMixBuilder : ImRoaBuilder
module.Inject(injection);
}
public T GetModule<T>()
public T? GetModule<T>()
{
return Modules.OfType<T>().FirstOrDefault();
}
+3 -3
View File
@@ -5,13 +5,13 @@ public interface ICallRequest
Guid CallRequestId { get; internal set; }
int CommandId { get; }
int ObjectId { get; }
object Parameter { get; }
object? Parameter { get; }
}
public class DefaultCallRequest : ICallRequest
{
public Guid CallRequestId { get; set; } = Guid.NewGuid();
public int CommandId { get; set; }
public int ObjectId { get; set; } = -1;
public int CommandId { get; init; }
public int ObjectId { get; init; } = -1;
public object? Parameter { get; set; }
}
+5 -2
View File
@@ -1,4 +1,7 @@
using System.Text.Json.Serialization;
using mROA.Abstract;
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace mROA.Implementation;
@@ -19,7 +22,7 @@ public class FinalCommandExecution<T> : FinalCommandExecution
public class TypedFinalCommandExecution : FinalCommandExecution<object>
{
[JsonIgnore]
public Type Type { get; set; }
public Type? Type { get; set; }
}
public class ExceptionCommandExecution : ICommandExecution
@@ -27,5 +30,5 @@ public class ExceptionCommandExecution : ICommandExecution
public Guid CallRequestId { get; init; }
public int ClientId { get; set; }
public int CommandId { get; set; }
public string Exeption { get; set; }
public required string Exception { get; set; }
}
@@ -1,59 +0,0 @@
// using System.Collections.Frozen;
//
// namespace mROA.Implementation;
//
// public class FrontendContextRepository(
// Dictionary<Type, Type> remoteTypes,
// ISerialisationModule.IFrontendSerialisationModule serialisationModule) : IContextRepository
// {
// private FrozenDictionary<Type, Type> _remoteTypes = remoteTypes.ToFrozenDictionary();
//
// public int ResisterObject(object o)
// {
// throw new NotSupportedException();
// }
//
// public void ClearObject(int id)
// {
// throw new NotSupportedException();
// }
//
// public object GetObject(int id)
// {
// throw new NotSupportedException();
// }
//
// public T GetObject<T>(int id)
// {
// if (_remoteTypes.TryGetValue(typeof(T), out var remoteType))
// {
// var remote = (T)Activator.CreateInstance(remoteType, id, serialisationModule)!;
// return remote;
// }
//
// throw new NotSupportedException();
// }
//
// public object GetSingleObject(Type type)
// {
// return Activator.CreateInstance(remoteTypes[type], -1, serialisationModule)!;
// }
//
// public int GetObjectIndex(object o)
// {
// if (o is IRemoteObject remote)
// {
// return remote.Id;
// }
//
// throw new NotSupportedException();
// }
//
// public void Inject<T>(T dependency)
// {
// }
//
// public void Bake()
// {
// }
// }
@@ -1,12 +1,14 @@
namespace mROA.Implementation;
using mROA.Abstract;
namespace mROA.Implementation.Frontend;
public class FrontendServiceBuilder
{
protected IInteractionModule.IFrontendInteractionModule _interactionModule;
protected ISerialisationModule.IFrontendSerialisationModule _serialisationModule;
protected IInteractionModule.IFrontendInteractionModule? InteractionModule;
protected ISerialisationModule.IFrontendSerialisationModule? SerialisationModule;
public ISerialisationModule.IFrontendSerialisationModule Build()
{
return _serialisationModule;
return SerialisationModule!;
}
}
@@ -1,21 +1,25 @@
using System.Text;
using System.Text.Json;
using mROA.Abstract;
namespace mROA.Implementation;
namespace mROA.Implementation.Frontend;
public class JsonFrontendSerialisationModule
: ISerialisationModule.IFrontendSerialisationModule
{
private IInteractionModule.IFrontendInteractionModule _interactionModule;
private IInteractionModule.IFrontendInteractionModule? _interactionModule;
public async Task<T> GetNextCommandExecution<T>(Guid requestId) where T : ICommandExecution
{
if (_interactionModule is null)
throw new Exception("Interaction module not initialized");
var receiveMessage = await _interactionModule.ReceiveMessage();
var parsed = JsonSerializer.Deserialize<T>(receiveMessage);
var parsed = JsonSerializer.Deserialize<T>(receiveMessage)!;
while (parsed.CallRequestId != requestId)
{
receiveMessage = await _interactionModule.ReceiveMessage();
parsed = JsonSerializer.Deserialize<T>(receiveMessage);
parsed = JsonSerializer.Deserialize<T>(receiveMessage)!;
}
return parsed;
@@ -23,19 +27,22 @@ public class JsonFrontendSerialisationModule
public async Task<FinalCommandExecution<T>> GetFinalCommandExecution<T>(Guid requestId)
{
if (_interactionModule is null)
throw new Exception("Interaction module not initialized");
var receiveMessage = await _interactionModule.ReceiveMessage();
// var str = Encoding.UTF8.GetString(receiveMessage);
var document = JsonDocument.Parse(receiveMessage);
if (document.RootElement.TryGetProperty("Exeption", out var exeptionElement))
if (document.RootElement.TryGetProperty("Exception", out var exceptionElement))
{
throw new RemoteException(exeptionElement.GetString()) { CallRequestId = requestId };
throw new RemoteException(exceptionElement.GetString()!) { CallRequestId = requestId };
}
var parsed = document.Deserialize<FinalCommandExecution<T>>();
var parsed = document.Deserialize<FinalCommandExecution<T>>()!;
while (parsed.CallRequestId != requestId)
{
receiveMessage = await _interactionModule.ReceiveMessage();
parsed = JsonSerializer.Deserialize<FinalCommandExecution<T>>(receiveMessage);
parsed = JsonSerializer.Deserialize<FinalCommandExecution<T>>(receiveMessage)!;
}
parsed.Result = parsed.Result! is JsonElement e ? e.Deserialize<T>() : (T)parsed.Result!;
@@ -44,6 +51,9 @@ public class JsonFrontendSerialisationModule
public void PostCallRequest(ICallRequest callRequest)
{
if (_interactionModule is null)
throw new Exception("Interaction module not initialized");
var post = JsonSerializer.Serialize(callRequest, callRequest.GetType());
_interactionModule.PostMessage(Encoding.UTF8.GetBytes(post));
}
@@ -2,21 +2,28 @@ using System.Net;
using System.Net.Sockets;
using mROA.Abstract;
namespace mROA.Implementation;
namespace mROA.Implementation.Frontend;
public class NetworkFrontendBridge : IFrontendBridge
public class NetworkFrontendBridge(IPEndPoint ipEndPoint) : IFrontendBridge
{
private TcpClient _tcpClient;
public NetworkFrontendBridge(IPEndPoint serverEndPoint)
{
_tcpClient = new TcpClient();
_tcpClient.Connect(serverEndPoint);
}
private readonly TcpClient _tcpClient = new();
private StreamBasedFrontendInteractionModule? _interactionModule;
public void Inject<T>(T dependency)
{
if (dependency is StreamBasedFrontendInteractionModule interactionModule)
{
interactionModule.ServerStream = _tcpClient.GetStream();
_interactionModule = interactionModule;
}
}
public void Connect()
{
_tcpClient.Connect(ipEndPoint);
if (_interactionModule is null)
{
throw new Exception("Interaction module was not injected");
}
_interactionModule.ServerStream = _tcpClient.GetStream();
}
}
@@ -1,11 +1,15 @@
namespace mROA.Implementation;
using mROA.Abstract;
namespace mROA.Implementation.Frontend;
public class StreamBasedFrontendInteractionModule : IInteractionModule.IFrontendInteractionModule
{
public Stream ServerStream { get; set; }
public Stream? ServerStream { get; set; }
public async Task<byte[]> ReceiveMessage()
{
if (ServerStream is null)
throw new IOException("Server is not connected.");
const int bufferSize = ushort.MaxValue;
byte[] buffer = new byte[bufferSize];
@@ -20,6 +24,9 @@ public class StreamBasedFrontendInteractionModule : IInteractionModule.IFrontend
public void PostMessage(byte[] message)
{
if (ServerStream is null)
throw new IOException("Server is not connected.");
ServerStream.Write(BitConverter.GetBytes((ushort)message.Length), 0, sizeof(ushort));
ServerStream.Write(message, 0, message.Length);
}
+3 -1
View File
@@ -1,4 +1,6 @@
using System.Reflection;
using mROA.Abstract;
using mROA.Implementation.Attributes;
namespace mROA.Implementation;
@@ -9,7 +11,7 @@ public class MethodRepository : IMethodRepository
public MethodInfo GetMethod(int id)
{
if (_methods.Count <= id)
return null;
throw new Exception("Method such registered method");
return _methods[id];
}
+13 -11
View File
@@ -1,32 +1,34 @@
using System.Text.Json.Serialization;
using mROA.Abstract;
namespace mROA.Implementation;
public static class TransmissionConfig
{
public static IContextRepository DefaultContextRepository { get; set; }
public static IContextRepository? DefaultContextRepository { get; set; }
}
public class TransmittedSharedObject<T>
public class TransmittedSharedObject<T> where T : notnull
{
public int ContextId { get; set; } = -1;
private static IContextRepository GetDefaultContextRepository() => TransmissionConfig.DefaultContextRepository ??
throw new NullReferenceException(
"DefaultContextRepository was not defined");
private int ContextId { get; init; } = -1;
[JsonIgnore]
public T? Value => TransmissionConfig.DefaultContextRepository.GetObject<T>(ContextId);
public T? Value => GetDefaultContextRepository().GetObject<T>(ContextId);
[JsonIgnore]
public IContextRepository Context { get; set; }
public TransmittedSharedObject()
private TransmittedSharedObject()
{
}
public TransmittedSharedObject(T value)
public TransmittedSharedObject(T value)
{
ContextId = TransmissionConfig.DefaultContextRepository.GetObjectIndex(value);
ContextId = GetDefaultContextRepository().GetObjectIndex(value);
}
public static implicit operator T(TransmittedSharedObject<T> value) => value.Value!;
public static implicit operator TransmittedSharedObject<T>(T value) =>
new() { ContextId = TransmissionConfig.DefaultContextRepository.GetObjectIndex(value) };
new() { ContextId = GetDefaultContextRepository().GetObjectIndex(value) };
}