protected override void AddEventHandlerDefinition <TEventArgs>( RpcEventInfo eventInfo, Func <RpcObjectRequest, IServiceProvider?, IRpcAsyncStreamWriter <TEventArgs>, IRpcContext, ValueTask> beginEventProducer, RpcStub <TService> serviceStub, IGrpcMethodBinder binder) { GrpcCore.ServerStreamingServerMethod <RpcObjectRequest, TEventArgs> handler = (request, responseStream, context) => { using (var scope = CreateServiceScope(serviceStub)) { return(beginEventProducer(request, scope?.ServiceProvider, new GrpcAsyncStreamWriter <TEventArgs>(responseStream), new GrpcCallContext(context)).AsTask()); } }; var beginEventProducerName = $"Begin{eventInfo.Name}"; binder.AddMethod( GrpcMethodDefinition.Create <RpcObjectRequest, TEventArgs>( GrpcCore.MethodType.ServerStreaming, eventInfo.FullServiceName, beginEventProducerName, serviceStub.Serializer), handler); }
protected override void AddCallbackMethodCore <TRequest, TReturn, TResponseReturn>( Func <TService, TRequest, Action <TReturn>, CancellationToken, Task> serviceCaller, Func <TReturn, TResponseReturn>?responseConverter, RpcServerFaultHandler faultHandler, RpcStub <TService> serviceStub, RpcOperationInfo operationInfo, IGrpcMethodBinder binder) where TResponseReturn : class { var serializer = serviceStub.Serializer; GrpcCore.ServerStreamingServerMethod <TRequest, TResponseReturn> handler = (request, responseStream, context) => { using (var serviceScope = CreateServiceScope(serviceStub)) { return(serviceStub.CallCallbackMethod( request, serviceScope?.ServiceProvider, new GrpcCallContext(context), new GrpcAsyncStreamWriter <TResponseReturn>(responseStream), serviceCaller, responseConverter, faultHandler, serializer).AsTask()); } }; binder.AddMethod( GrpcMethodDefinition.Create <TRequest, TResponseReturn>( GrpcCore.MethodType.ServerStreaming, operationInfo.FullServiceName, operationInfo.Name, serviceStub.Serializer), handler); }
protected override void AddGenericBlockingMethodCore <TRequest, TReturn, TResponseReturn>( Func <TService, TRequest, CancellationToken, TReturn> serviceCaller, Func <TReturn, TResponseReturn>?responseConverter, RpcServerFaultHandler faultHandler, RpcStub <TService> serviceStub, RpcOperationInfo operationInfo, IGrpcMethodBinder binder) { var serializer = serviceStub.Serializer; Task <RpcResponse <TResponseReturn> > handler(TRequest request, GrpcCore.ServerCallContext context) { using (var serviceScope = CreateServiceScope(serviceStub)) { return(serviceStub.CallBlockingMethod( request, new GrpcCallContext(context), serviceCaller, responseConverter, faultHandler, serializer, serviceScope?.ServiceProvider).AsTask()); } } binder.AddMethod( GrpcMethodDefinition.Create <TRequest, RpcResponse <TResponseReturn> >(GrpcCore.MethodType.Unary, operationInfo.FullServiceName, operationInfo.Name, serializer), handler); }
protected override void AddCallbackMethodCore <TRequest, TReturn, TResponseReturn>( Func <TService, TRequest, Action <TReturn>, CancellationToken, Task> serviceCaller, Func <TReturn, TResponseReturn>?responseConverter, RpcServerFaultHandler faultHandler, RpcStub <TService> serviceStub, RpcOperationInfo operationInfo, INetGrpcBinder <TService> binder) { var serializer = serviceStub.Serializer; ServerStreamingServerMethod <NetGrpcServiceActivator <TService>, TRequest, TResponseReturn> handler = (activator, request, responseStream, context) => { return(serviceStub.CallCallbackMethod( request, activator.ServiceProvider, new GrpcCallContext(context), new GrpcAsyncStreamWriter <TResponseReturn>(responseStream), serviceCaller, responseConverter, faultHandler, serializer).AsTask()); }; var methodStub = GrpcMethodDefinition.Create <TRequest, TResponseReturn>( MethodType.ServerStreaming, operationInfo.FullServiceName, operationInfo.Name, serializer); binder.AddServerStreamingMethod(methodStub, operationInfo.Metadata, handler); }
protected override void AddGenericBlockingMethodCore <TRequest, TReturn, TResponseReturn>( Func <TService, TRequest, CancellationToken, TReturn> serviceCaller, Func <TReturn, TResponseReturn>?responseConverter, RpcServerFaultHandler faultHandler, RpcStub <TService> serviceStub, RpcOperationInfo operationInfo, INetGrpcBinder <TService> binder) { var serializer = serviceStub.Serializer; Task <RpcResponse <TResponseReturn> > Handler(NetGrpcServiceActivator <TService> activator, TRequest request, ServerCallContext context) => serviceStub.CallBlockingMethod( request, new GrpcCallContext(context), serviceCaller, responseConverter, faultHandler, serializer, activator.ServiceProvider).AsTask(); var methodStub = GrpcMethodDefinition.Create <TRequest, RpcResponse <TResponseReturn> >( MethodType.Unary, operationInfo.FullServiceName, operationInfo.Name, serializer); binder.AddUnaryMethod(methodStub, operationInfo.Metadata, Handler); }
protected override void AddEventHandlerDefinition <TEventArgs>( RpcEventInfo eventInfo, Func <RpcObjectRequest, IServiceProvider?, IRpcAsyncStreamWriter <TEventArgs>, IRpcContext, ValueTask> beginEventProducer, RpcStub <TService> serviceStub, ILightweightMethodBinder binder) { var beginEventProducerName = $"{eventInfo.FullServiceName}.Begin{eventInfo.Name}"; var methodStub = new LightweightStreamingMethodStub <RpcObjectRequest, TEventArgs>(beginEventProducerName, beginEventProducer, serviceStub.Serializer, null); binder.AddMethod(methodStub); }
protected override void AddCallbackMethodCore <TRequest, TReturn, TResponse>( Func <TService, TRequest, Action <TReturn>, CancellationToken, Task> serviceCaller, Func <TReturn, TResponse>?responseConverter, RpcServerFaultHandler faultHandler, RpcStub <TService> serviceStub, RpcOperationInfo operationInfo, ILightweightMethodBinder binder) { var serializer = serviceStub.Serializer; ValueTask HandleRequest(TRequest request, IServiceProvider?serviceProvider, IRpcAsyncStreamWriter <TResponse> responseWriter, LightweightCallContext context) => serviceStub.CallCallbackMethod(request, serviceProvider, context, responseWriter, serviceCaller, responseConverter, faultHandler, serializer); var methodStub = new LightweightStreamingMethodStub <TRequest, TResponse>(operationInfo.FullName, HandleRequest, serializer, faultHandler); binder.AddMethod(methodStub); }
protected override void AddGenericVoidBlockingMethodCore <TRequest>( Action <TService, TRequest, CancellationToken> serviceCaller, RpcServerFaultHandler faultHandler, RpcStub <TService> serviceStub, RpcOperationInfo operationInfo, ILightweightMethodBinder binder) { var serializer = operationInfo.SerializerOverride ?? serviceStub.Serializer; ValueTask <RpcResponse> HandleRequest(TRequest request, IServiceProvider?serviceProvider, LightweightCallContext context) => serviceStub.CallVoidBlockingMethod(request, serviceProvider, context, serviceCaller, faultHandler, serializer); var methodStub = new LightweightMethodStub <TRequest, RpcResponse>(operationInfo.FullName, HandleRequest, serializer, faultHandler, operationInfo.AllowInlineExecution); binder.AddMethod(methodStub); }
protected override void AddEventHandlerDefinition <TEventArgs>( RpcEventInfo eventInfo, Func <RpcObjectRequest, IServiceProvider?, IRpcAsyncStreamWriter <TEventArgs>, IRpcContext, ValueTask> beginEventProducer, RpcStub <TService> serviceStub, INetGrpcBinder <TService> binder) { ServerStreamingServerMethod <NetGrpcServiceActivator <TService>, RpcObjectRequest, TEventArgs> handler = (activator, request, responseStream, context) => beginEventProducer(request, activator.ServiceProvider, new GrpcAsyncStreamWriter <TEventArgs>(responseStream), new GrpcCallContext(context)).AsTask(); var beginEventProducerName = $"Begin{eventInfo.Name}"; binder.AddServerStreamingMethod( GrpcMethodDefinition.Create <RpcObjectRequest, TEventArgs>( MethodType.ServerStreaming, eventInfo.FullServiceName, beginEventProducerName, serviceStub.Serializer), eventInfo.Metadata, handler); }
protected override void AddGenericVoidBlockingMethodCore <TRequest>( Action <TService, TRequest, CancellationToken> serviceCaller, RpcServerFaultHandler faultHandler, RpcStub <TService> serviceStub, RpcOperationInfo operationInfo, IGrpcMethodBinder binder) { var serializer = serviceStub.Serializer; GrpcCore.UnaryServerMethod <TRequest, RpcResponse> handler = (request, context) => { using (var serviceScope = CreateServiceScope(serviceStub)) { return(serviceStub.CallVoidBlockingMethod( request, serviceScope?.ServiceProvider, new GrpcCallContext(context), serviceCaller, faultHandler, serializer).AsTask()); } }; binder.AddMethod( GrpcMethodDefinition.Create <TRequest, RpcResponse>(GrpcCore.MethodType.Unary, operationInfo.FullServiceName, operationInfo.Name, serializer), handler); }
void Initialize() { lock (initializeLock) { if (initialized) { return; } initialized = true; if (handleImplicit && handle == null) { // retrieve handle default value string handlePropertyName = proxiedType.Name + ".handle"; handle = TestSite.Properties[handlePropertyName]; if (handle == null) { throw new InvalidOperationException( String.Format("RPC adapter with implicit handle passing has undefined handle. Set property '{0}' in the configuration.", handlePropertyName)); } } string dllPropertyName = proxiedType.Name + ".dllimport"; string stubDllName = TestSite.Properties[dllPropertyName]; if (stubDllName == null) { stubDllName = proxiedType.Name.ToLower() + "_rpcstubs.dll"; } string stubDllNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(stubDllName) + "_" + Guid.NewGuid(); string dllName = stubDllNameWithoutExtension + ".dll"; msr = new Marshaler(site, NativeMarshalingConfiguration.Configuration); AppDomain currentDomain = AppDomain.CurrentDomain; string assName = "pinvoke_" + stubDllNameWithoutExtension; string fileName = string.Empty; string tempFileName = TryGetTempFileName(); bool useTempFile = false; if (!string.IsNullOrEmpty(tempFileName)) { useTempFile = true; fileName = Path.GetFileName(tempFileName); } else { fileName = assName + ".dll"; tempFileName = fileName; } //Copy the stub dll into the same directory as the pinvoke assembly. string tempDir = Path.GetDirectoryName(tempFileName); CopyStub(stubDllName, tempDir, dllName); AssemblyName assemblyName = new AssemblyName(assName); AssemblyBuilder assemblyBuilder = null; if (useTempFile) { assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save, Path.GetTempPath()); } else { assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save); } ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assName, fileName); TypeBuilder typeBuilder = moduleBuilder.DefineType(assName); foreach (MethodInfo method in proxiedType.GetMethods(BindingFlags.Public | BindingFlags.Instance)) { ParameterInfo[] paramInfos = method.GetParameters(); RpcStub stub = new RpcStub(); Type[] stubParameterTypes = new Type[paramInfos.Length]; stub.parameters = new RpcParameter[paramInfos.Length]; stub.proxyMethod = method; for (int i = 0; i < paramInfos.Length; i++) { ParameterInfo paramInfo = paramInfos[i]; Type proxyType = paramInfo.ParameterType; Type nativeType; if (proxyType.IsByRef) { proxyType = proxyType.GetElementType(); nativeType = typeof(IntPtr); } else { nativeType = GetNativeType(paramInfo, proxyType); } stubParameterTypes[i] = nativeType; stub.parameters[i] = new RpcParameter(paramInfo, proxyType, nativeType); } stub.returnParameter = new RpcParameter(method.ReturnParameter, method.ReturnType, GetNativeType(method.ReturnParameter, method.ReturnType)); if (handleImplicit) { List <Type> stubParametersTypeList = new List <Type>(stubParameterTypes); stubParametersTypeList.Insert(0, typeof(IntPtr)); stubParameterTypes = stubParametersTypeList.ToArray(); } stub.stubBuilder = typeBuilder.DefinePInvokeMethod( method.Name, dllName, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl, CallingConventions.Standard, stub.returnParameter.nativeType, stubParameterTypes, callingConvention, charset); stub.stubBuilder.SetImplementationFlags(MethodImplAttributes.PreserveSig); stubs[method] = stub; } typeBuilder.CreateType(); // Build types for memory management types. string UserRpcMemMgmtTypeName = "UserRpcMemMgmt"; string userFreeMethodName = "MIDL_user_free"; TypeBuilder UserRpcMemMgmtBuilder = moduleBuilder.DefineType(UserRpcMemMgmtTypeName); BuildMemoryManagementType(UserRpcMemMgmtBuilder, typeof(UserRpcMemoryManagement), dllName); // Save and reload the pinvoke assembly try { assemblyBuilder.Save(fileName); } catch (IOException e) { throw new InvalidOperationException( String.Format("cannot create P/Invoke stub assembly {0}: {1}", fileName, e.Message)); } Assembly reloaded = null; if (useTempFile) { reloaded = Assembly.LoadFrom(tempFileName); } else { reloaded = Assembly.LoadFrom(fileName); } Type stubType = reloaded.GetType(assName); foreach (RpcStub stub in stubs.Values) { stub.stubMethod = stubType.GetMethod(stub.proxyMethod.Name); } string fullDllName = dllName; if (useTempFile) { fullDllName = Path.Combine(tempDir, dllName); } if (NativeMethods.HasMethod(fullDllName, userFreeMethodName)) { Type userRpcMemMgmtType = reloaded.GetType(UserRpcMemMgmtTypeName); rpcFreeMethod = userRpcMemMgmtType.GetMethod(userFreeMethodName); } } }
private static IServiceScope?CreateServiceScope(RpcStub stub) { // TODO: Maybe RpcStub should have the server as a type // parameter to avoid this cast? return(stub.Server.ServiceProvider?.CreateScope()); }
void Initialize() { lock (initializeLock) { if (initialized) return; initialized = true; if (handleImplicit && handle == null) { // retrieve handle default value string handlePropertyName = proxiedType.Name + ".handle"; handle = TestSite.Properties[handlePropertyName]; if (handle == null) throw new InvalidOperationException( String.Format("RPC adapter with implicit handle passing has undefined handle. Set property '{0}' in the configuration.", handlePropertyName)); } string dllPropertyName = proxiedType.Name + ".dllimport"; string stubDllName = TestSite.Properties[dllPropertyName]; if (stubDllName == null) stubDllName = proxiedType.Name.ToLower() + "_rpcstubs.dll"; string stubDllNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(stubDllName) + "_" + Guid.NewGuid(); string dllName = stubDllNameWithoutExtension + ".dll"; msr = new Marshaler(site, NativeMarshalingConfiguration.Configuration); AppDomain currentDomain = AppDomain.CurrentDomain; string assName = "pinvoke_" + stubDllNameWithoutExtension; string fileName = string.Empty; string tempFileName = TryGetTempFileName(); bool useTempFile = false; if (!string.IsNullOrEmpty(tempFileName)) { useTempFile = true; fileName = Path.GetFileName(tempFileName); } else { fileName = assName + ".dll"; tempFileName = fileName; } //Copy the stub dll into the same directory as the pinvoke assembly. string tempDir = Path.GetDirectoryName(tempFileName); CopyStub(stubDllName, tempDir, dllName); AssemblyName assemblyName = new AssemblyName(assName); AssemblyBuilder assemblyBuilder = null; if (useTempFile) { assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save, Path.GetTempPath()); } else { assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save); } ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assName, fileName); TypeBuilder typeBuilder = moduleBuilder.DefineType(assName); foreach (MethodInfo method in proxiedType.GetMethods(BindingFlags.Public | BindingFlags.Instance)) { ParameterInfo[] paramInfos = method.GetParameters(); RpcStub stub = new RpcStub(); Type[] stubParameterTypes = new Type[paramInfos.Length]; stub.parameters = new RpcParameter[paramInfos.Length]; stub.proxyMethod = method; for (int i = 0; i < paramInfos.Length; i++) { ParameterInfo paramInfo = paramInfos[i]; Type proxyType = paramInfo.ParameterType; Type nativeType; if (proxyType.IsByRef) { proxyType = proxyType.GetElementType(); nativeType = typeof(IntPtr); } else { nativeType = GetNativeType(paramInfo, proxyType); } stubParameterTypes[i] = nativeType; stub.parameters[i] = new RpcParameter(paramInfo, proxyType, nativeType); } stub.returnParameter = new RpcParameter(method.ReturnParameter, method.ReturnType, GetNativeType(method.ReturnParameter, method.ReturnType)); if (handleImplicit) { List<Type> stubParametersTypeList = new List<Type>(stubParameterTypes); stubParametersTypeList.Insert(0, typeof(IntPtr)); stubParameterTypes = stubParametersTypeList.ToArray(); } stub.stubBuilder = typeBuilder.DefinePInvokeMethod( method.Name, dllName, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl, CallingConventions.Standard, stub.returnParameter.nativeType, stubParameterTypes, callingConvention, charset); stub.stubBuilder.SetImplementationFlags(MethodImplAttributes.PreserveSig); stubs[method] = stub; } typeBuilder.CreateType(); // Build types for memory management types. string UserRpcMemMgmtTypeName = "UserRpcMemMgmt"; string userFreeMethodName = "MIDL_user_free"; TypeBuilder UserRpcMemMgmtBuilder = moduleBuilder.DefineType(UserRpcMemMgmtTypeName); BuildMemoryManagementType(UserRpcMemMgmtBuilder, typeof(UserRpcMemoryManagement), dllName); // Save and reload the pinvoke assembly try { assemblyBuilder.Save(fileName); } catch (IOException e) { throw new InvalidOperationException( String.Format("cannot create P/Invoke stub assembly {0}: {1}", fileName, e.Message)); } Assembly reloaded = null; if (useTempFile) { reloaded = Assembly.LoadFrom(tempFileName); } else { reloaded = Assembly.LoadFrom(fileName); } Type stubType = reloaded.GetType(assName); foreach (RpcStub stub in stubs.Values) { stub.stubMethod = stubType.GetMethod(stub.proxyMethod.Name); } string fullDllName = dllName; if (useTempFile) { fullDllName = Path.Combine(tempDir, dllName); } if (NativeMethods.HasMethod(fullDllName, userFreeMethodName)) { Type userRpcMemMgmtType = reloaded.GetType(UserRpcMemMgmtTypeName); rpcFreeMethod = userRpcMemMgmtType.GetMethod(userFreeMethodName); } } }