public async Task <TResult> Call <TResult>(Func <T, Task <TResult> > func, LogSlice logSlice) { var channel = _factory.CreateChannel(); //Почему важно закрывать клиента: //https://stackoverflow.com/a/7184555 //https://stackoverflow.com/a/7271088 //Если возникнет необходимость, то в будущем следует реализовать //более сложный вариант закрытия, как описано по ссылкам: //https://stackoverflow.com/a/573925 //https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/avoiding-problems-with-the-using-statement //https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/expected-exceptions using ((IClientChannel)channel) { _asyncLocal.Value = logSlice; try { return(await func(channel)); } finally { _asyncLocal.Value = null; } } }
static async Task Main() { Log.Logger = new LoggerConfiguration() .Enrich.WithThreadId() .Enrich.FromLogContext() //.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} {SourceContext}] {Message:lj}{NewLine}{Exception}") .WriteTo.File("log.txt") .WriteTo.Seq("http://localhost:5341") .CreateLogger(); var builder = new ContainerBuilder(); builder.RegisterGeneric(typeof(RemoteCaller <>)) .As(typeof(IRemoteCaller <>)) .SingleInstance(); builder.RegisterAssemblyTypes(typeof(Program).Assembly) .Where(t => t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IRemoteCallConfiguration <>))) .AsImplementedInterfaces(); builder.RegisterLogger(); var container = builder.Build(); Console.WriteLine(await container.Resolve <IRemoteCaller <IService1> >() .Call(service => service.GetDataAsync(123), LogSlice.Deposit(DateTime.Now.Ticks))); Console.WriteLine(await container.Resolve <IRemoteCaller <IService1> >() .Call(service => service.GetDataAsync(123), LogSlice.Deposit(DateTime.Now.Ticks))); Log.CloseAndFlush(); }