using System; using System.Collections.Concurrent; using System.Linq; using System.Reflection; using ZeroLevel.Logging; using ZeroLevel.Services.Invokation; using ZeroLevel.Services.Serialization; namespace TestApp { public record LogMessage(LogLevel Level, T Message); internal interface ILogMessageBuffer : IDisposable { long Count(); void Push(LogLevel level, T message); LogMessage Take(); } internal sealed class NoLimitedLogMessageBuffer : ILogMessageBuffer { private readonly BlockingCollection> _messageQueue = new BlockingCollection>(); private bool _isDisposed = false; public long Count() { if (_messageQueue.IsCompleted) return 0; return _messageQueue.Count; } public void Dispose() { if (!_isDisposed) { _isDisposed = true; _messageQueue.Dispose(); } } public void Push(LogLevel level, T message) { if (_isDisposed) return; _messageQueue.Add(new LogMessage(level, message)); } public LogMessage Take() { return _messageQueue.Take(); } } internal static class Program { private class LogQueueWrapper { private string TakeMethod; private string PushMethod; private object Target; public IInvokeWrapper Invoker; public LogMessage Take() { return (LogMessage)Invoker.Invoke(Target, TakeMethod); } public void Push(LogLevel level, LogMessage value) { Invoker.Invoke(Target, PushMethod, new object[] { level, value }); } public static LogQueueWrapper Create(object target) { var wrapper = new LogQueueWrapper { Invoker = InvokeWrapper.Create(), Target = target }; wrapper.PushMethod = wrapper.Invoker.ConfigureGeneric(typeof(T), "Push").First(); wrapper.TakeMethod = wrapper.Invoker.ConfigureGeneric(typeof(T), "Take").First(); return wrapper; } } private static Func CreateArrayPredicate() { var typeArg = typeof(T).GetElementType(); return mi => mi.Name.Equals("WriteArray", StringComparison.Ordinal) && mi.GetParameters().First().ParameterType.GetElementType().IsAssignableFrom(typeArg); } private static Func CreateCollectionPredicate() { var typeArg = typeof(T).GetGenericArguments().First(); return mi => mi.Name.Equals("WriteCollection", StringComparison.Ordinal) && mi.GetParameters().First().ParameterType.GetGenericArguments().First().IsAssignableFrom(typeArg); } private static void Main(string[] args) { var wrapper = new Wrapper { Invoker = InvokeWrapper.Create() }; var ReadId = wrapper.Invoker.Configure(typeof(MemoryStreamReader), "ReadDateTimeArray").First(); var WriteId = wrapper.Invoker.Configure(typeof(MemoryStreamWriter), CreateArrayPredicate()).First(); Console.Write(WriteId); } } }