private void CreateGrpcMethodForCqrsChannel <TRequest, TResponse, TChRequest, TChResponse, TChResponseEnvelope>(GrpcServer server, string serverId, CqrsChannelInfo info) where TRequest : class where TResponse : class where TChRequest : class where TChResponse : class where TChResponseEnvelope : class { var builder = ServerServiceDefinition.CreateBuilder(); var method = GrpcMethodFactoryUtil.CreateGrpcMethod <TChRequest, TChResponseEnvelope>(info.ServiceName, info.MethodName); var handler = new UnaryServerMethod <TChRequest, TChResponseEnvelope>(async(chReq, ctx) => { // timeout var cancellationToken = ctx.CancellationToken.AddTimeout(_configuration.TimeoutMs); // execute in scope using (Scope scope = AsyncScopedLifestyle.BeginScope(_container)) { // execute method var chRspEnv = await GrpcChannelHandlerUtil.HandleChannelRequest <TRequest, TResponse, TChRequest, TChResponse, TChResponseEnvelope>( scope.Container, _mapper, ctx, serverId, info, chReq, cancellationToken); return(chRspEnv); } }); // add method to server builder.AddMethod(method, handler); var service = builder.Build(); server.Services.Add(service); }
public void OnServiceMethodDiscovery(ServiceMethodProviderContext <GrpcService> context) { // mapper var mapperValidator = _cfg.MapperValidator != null?Activator.CreateInstance(_cfg.MapperValidator) as IPropertyMapValidator : null; var mapper = _cqrs.CreateMapper(mapperValidator); // set server id for logging var serverId = !string.IsNullOrWhiteSpace(_cfg.ServerId) ? _cfg.ServerId : Assembly.GetEntryAssembly().FullName.Split(',')[0]; // create methos var methodAddGeneric = GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).First(x => x.Name == nameof(AddMethod)); _cqrs.ToCqrsChannelInfo().ToList().ForEach(x => { var method = GrpcMethodFactoryUtil.CreateGrpcMethodGeneric(x); var invokeMethod = GrpcServerMethodFactoryUtil.CreateServerMethodGeneric(_container, serverId, x, mapper, _cfg.TimeoutMs); var methodAdd = methodAddGeneric.MakeGenericMethod(x.ChReqType, x.ChRspEnvType); methodAdd.Invoke(this, new object[] { context, method, invokeMethod }); }); }