Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
                }
            }
        }
Пример #12
0
 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);
                }
            }
        }