diff --git a/HandyIpc.Generator/ClientProxy.cs b/HandyIpc.Generator/ClientProxy.cs index a28eb3e..2eed384 100644 --- a/HandyIpc.Generator/ClientProxy.cs +++ b/HandyIpc.Generator/ClientProxy.cs @@ -30,17 +30,19 @@ public class {nameof(ClientProxy)}{className}{typeParameters} : {interfaceType} private readonly Sender _sender; private readonly ISerializer _serializer; private readonly string _key; +{Text(events.Any() ? @" private readonly AwaiterManager _awaiterManager; +" : RemoveLineIfEmpty)} {events.For(item => $@" private event {item.Type.ToTypeDeclaration()} _{item.Name}; ")} - {events.For(item => { - var eSymbol = ((INamedTypeSymbol)item.Type).DelegateInvokeMethod!.Parameters[1]; + IParameterSymbol eSymbol = ((INamedTypeSymbol)item.Type).DelegateInvokeMethod!.Parameters[1]; string eType = eSymbol.Type.ToTypeDeclaration(); return $@" + public event {item.Type.ToTypeDeclaration()} {item.Name} {{ add @@ -65,7 +67,6 @@ public class {nameof(ClientProxy)}{className}{typeParameters} : {interfaceType} }} }} }} - "; })} @@ -74,7 +75,9 @@ public class {nameof(ClientProxy)}{className}{typeParameters} : {interfaceType} _sender = sender; _serializer = serializer; _key = key; +{Text(events.Any() ? @" _awaiterManager = new AwaiterManager(key, sender, serializer); +" : RemoveLineIfEmpty)} }} {methods.For(method => { diff --git a/HandyIpc.Generator/Dispatcher.cs b/HandyIpc.Generator/Dispatcher.cs index cab5de2..16ff318 100644 --- a/HandyIpc.Generator/Dispatcher.cs +++ b/HandyIpc.Generator/Dispatcher.cs @@ -26,7 +26,7 @@ namespace {@namespace} [global::System.Diagnostics.DebuggerNonUserCode] [global::System.Reflection.Obfuscation(Exclude = true)] [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public class {nameof(Dispatcher)}{className}{typeParameters} : IMethodDispatcher + public class {nameof(Dispatcher)}{className}{typeParameters} : IMethodDispatcher{(events.Any() ? ", INotifiable" : null)} {@interface.TypeParameters.For(typeParameter => $@" {typeParameter.ToGenericConstraint()} ")} @@ -36,8 +36,10 @@ public class {nameof(Dispatcher)}{className}{typeParameters} : IMethodDispatcher private readonly Lazy> _genericMethodMapping; " : RemoveLineIfEmpty)} - public NotifierManager NotifierManager {{ get; set; }} +{Text(events.Any() ? @" + public NotifierManager NotifierManager { get; set; } +" : RemoveLineIfEmpty)} public {nameof(Dispatcher)}{className}({interfaceType} instance) {{ _instance = instance; @@ -45,10 +47,9 @@ public class {nameof(Dispatcher)}{className}{typeParameters} : IMethodDispatcher _genericMethodMapping = new Lazy>( () => GeneratorHelper.GetGenericMethodMapping(typeof({interfaceType}), _instance)); " : RemoveLineIfEmpty)} - {events.For(item => $@" instance.{item.Name} += (_, e) => NotifierManager.Publish(""{item.Name}"", e); -", RemoveLineIfEmpty)} +")} }} public async Task Dispatch(Context ctx, Func next) diff --git a/HandyIpc.Tests/EventTypeTest.cs b/HandyIpc.Tests/EventTypeTest.cs index 597eb3c..0f39140 100644 --- a/HandyIpc.Tests/EventTypeTest.cs +++ b/HandyIpc.Tests/EventTypeTest.cs @@ -1,5 +1,4 @@ using System; -using System.Threading.Tasks; using HandyIpc; using HandyIpcTests.Fixtures; using HandyIpcTests.Interfaces; diff --git a/HandyIpc/ContainerServerBuilder.cs b/HandyIpc/ContainerServerBuilder.cs index 3243a24..40e4105 100644 --- a/HandyIpc/ContainerServerBuilder.cs +++ b/HandyIpc/ContainerServerBuilder.cs @@ -54,9 +54,13 @@ public IContainerServer Build() ConcurrentDictionary notifiers = new(); foreach (var (key, type, factory) in _interfaceMap) { - IMethodDispatcher dispatcher = CreateDispatcher(type, factory); - dispatcher.NotifierManager = notifiers.GetOrAdd(key, _ => new NotifierManager(_serializerFactory())); - Middleware methodDispatcher = dispatcher.Dispatch; + object dispatcher = CreateDispatcher(type, factory); + if (dispatcher is INotifiable notifiable) + { + notifiable.NotifierManager = notifiers.GetOrAdd(key, _ => new NotifierManager(_serializerFactory())); + } + + Middleware methodDispatcher = ((IMethodDispatcher)dispatcher).Dispatch; map.Add(key, methodDispatcher); } @@ -65,11 +69,15 @@ public IContainerServer Build() Middleware methodDispatcher = Middlewares.GetMethodDispatcher( genericTypes => { - IMethodDispatcher dispatcher = CreateDispatcher( + object dispatcher = CreateDispatcher( type.MakeGenericType(genericTypes), () => factory(genericTypes)); - dispatcher.NotifierManager = notifiers.GetOrAdd(key, _ => new NotifierManager(_serializerFactory())); - return dispatcher; + if (dispatcher is INotifiable notifiable) + { + notifiable.NotifierManager = notifiers.GetOrAdd(key, _ => new NotifierManager(_serializerFactory())); + } + + return (IMethodDispatcher)dispatcher; }); map.Add(key, methodDispatcher); } @@ -78,13 +86,13 @@ public IContainerServer Build() Middlewares.Heartbeat, Middlewares.ExceptionHandler, Middlewares.GetHandleRequest(map), - Middlewares.GetHandleEvent(notifiers), + Middlewares.GetHandleSubscription(notifiers), Middlewares.NotFound); return new ContainerServer(_serverFactory(), middleware, _serializerFactory(), _loggerFactory()); } - private static IMethodDispatcher CreateDispatcher(Type interfaceType, Func factory) + private static object CreateDispatcher(Type interfaceType, Func factory) { object instance = factory(); @@ -105,9 +113,7 @@ private static IMethodDispatcher CreateDispatcher(Type interfaceType, Func : PoolBase where TValue : IDisposa private readonly Func> _factory; private readonly Func> _checkValue; - public AsyncPool(Func> factory, Func>? checkValue = null) + public AsyncPool(Func> factory, Func> checkValue) { _factory = factory; - _checkValue = checkValue ?? (_ => Task.FromResult(true)); + _checkValue = checkValue; } public async Task> RentAsync() diff --git a/HandyIpc/Core/IMethodDispatcher.cs b/HandyIpc/Core/IMethodDispatcher.cs index e50803e..bc85617 100644 --- a/HandyIpc/Core/IMethodDispatcher.cs +++ b/HandyIpc/Core/IMethodDispatcher.cs @@ -5,8 +5,6 @@ namespace HandyIpc.Core { public interface IMethodDispatcher { - NotifierManager NotifierManager { get; set; } - Task Dispatch(Context context, Func next); } } diff --git a/HandyIpc/Core/INotifiable.cs b/HandyIpc/Core/INotifiable.cs new file mode 100644 index 0000000..139b170 --- /dev/null +++ b/HandyIpc/Core/INotifiable.cs @@ -0,0 +1,7 @@ +namespace HandyIpc.Core +{ + public interface INotifiable + { + NotifierManager NotifierManager { get; set; } + } +} diff --git a/HandyIpc/Core/Middlewares.cs b/HandyIpc/Core/Middlewares.cs index 1c0ba38..e6e3ac6 100644 --- a/HandyIpc/Core/Middlewares.cs +++ b/HandyIpc/Core/Middlewares.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -54,7 +53,7 @@ public static Middleware GetHandleRequest(IReadOnlyDictionary notifiers) + public static Middleware GetHandleSubscription(IReadOnlyDictionary notifiers) { return async (ctx, next) => { @@ -64,12 +63,14 @@ public static Middleware GetHandleEvent(ConcurrentDictionary new NotifierManager(ctx.Serializer)); - manager.Subscribe(subscription.CallbackName, subscription.ProcessId, ctx.Connection); - ctx.Output = Signals.Unit; - ctx.KeepAlive = false; + if (notifiers.TryGetValue(subscription.Name, out NotifierManager manager)) + { + manager.Subscribe(subscription.CallbackName, subscription.ProcessId, ctx.Connection); + ctx.Output = Signals.Unit; + ctx.KeepAlive = false; + } } - break; + return; case SubscriptionType.Remove: { if (notifiers.TryGetValue(subscription.Name, out NotifierManager manager)) @@ -79,10 +80,8 @@ public static Middleware GetHandleEvent(ConcurrentDictionary : PoolBase where TValue : IDisposable private readonly Func _factory; private readonly Func _checkValue; - public Pool(Func factory, Func? checkValue = null) + public Pool(Func factory, Func checkValue) { _factory = factory; - _checkValue = checkValue ?? (_ => true); + _checkValue = checkValue; } public RentedValue Rent() diff --git a/HandyIpc/Core/Subscription.cs b/HandyIpc/Core/Subscription.cs index 3ce7146..96169d9 100644 --- a/HandyIpc/Core/Subscription.cs +++ b/HandyIpc/Core/Subscription.cs @@ -1,10 +1,9 @@ -using System; using System.Diagnostics; using System.Text; namespace HandyIpc.Core { - public enum SubscriptionType { Add, Promise, Remove } + public enum SubscriptionType { Add, Remove } public class Subscription { @@ -19,7 +18,7 @@ public class Subscription public string CallbackName { get; set; } = string.Empty; - public int ProcessId { get; } = InnerProcessId; + public int ProcessId => InnerProcessId; internal static bool TryParse(byte[] bytes, ISerializer serializer, out Subscription subscription) { @@ -45,11 +44,6 @@ internal static byte[] Add(string key, string name, ISerializer serializer) return GetBytes(SubscriptionType.Add, key, name, serializer); } - internal static byte[] Promise(string key, string name, ISerializer serializer) - { - return GetBytes(SubscriptionType.Promise, key, name, serializer); - } - internal static byte[] Remove(string key, string name, ISerializer serializer) { return GetBytes(SubscriptionType.Remove, key, name, serializer);