.netcore grpc客户端工厂及依赖注入使用

news2024/11/16 19:55:40

一、客户端工厂概述

  1. gRPC 与 HttpClientFactory 的集成提供了一种创建 gRPC 客户端的集中方式。
  2. 可以通过依赖包Grpc.Net.ClientFactory中的AddGrpcClient进行gRPC客户端依赖注入
  3. AddGrpcClient函数提供了许多配置项用于处理一些其他事项;例如AOP、重试策略等

二、案例介绍

  1. 创建一个WPF客户端
  2. 在App.xaml.cs代码类里重写OnStartup方法,进行依赖注入;需要注意的是在方法内设立窗口调用需要把展示端属性  xmlns: StartupUri="FieldWindow.xaml 给去掉
  3. 引用ServiceCollection做为容器集
  4. 注入gRPC工厂,注入windows窗体,以及其他需要用到的服务类等

三、客户端代码展示

  1. proto文件 可以看我之前的文章这里就不放上来了
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            IServiceCollection services = new ServiceCollection();
            // 注入
            services.AddWPFGrpc();

            AddWPFWindows(services);
            // 构建服务提供器
            var serviceProvider = services.BuildServiceProvider();

            var fieldWindow = serviceProvider.GetRequiredService<FieldWindow>();

            fieldWindow.Show();
        }

        private IServiceCollection AddWPFWindows(IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            var windowType = typeof(Window);
            var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.BaseType == windowType).ToList();
            foreach (var type in types)
            {
                services.AddScoped(type);
            }

            return services;
        }
    }
    public static class GrpcClient
    {
        /// <summary>
        /// rpc 工厂注入
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddWPFGrpc(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }
            services.AddGrpcClient<FieldRpc.FieldRpcClient>(options => options.Address = new Uri("https://localhost:7188"));

            return services;
        }
    }
    /// <summary>
    /// FieldWindow.xaml 的交互逻辑
    /// </summary>
    public partial class FieldWindow : Window
    {
        private readonly FieldRpc.FieldRpcClient _fieldRpcClient;

        public FieldWindow( FieldRpc.FieldRpcClient fieldRpcClient)
        {
            InitializeComponent();
            _fieldRpcClient = fieldRpcClient;
        }

        // 基础
        private async void BtnBaseconfig_Click(object sender, RoutedEventArgs e)
        {
            // 基础
            BaseConfig config = new BaseConfig();
            config.Name = "张三";
            config.Position = 2.33D;
            config.Distance = 5.48F;
            config.Age = 10;
            config.TimeSpanId = 6538590027736100;
            config.SAge = 1921;
            config.STimeSpanId = 6538590027736130;
            config.Flag = true;
            await _fieldRpcClient.BaseConfigServiceAsync(config);
            MessageBox();
        }

        // 日期
        private async void BtnDateconfig_Click(object sender, RoutedEventArgs e)
        {
            // 日期
            DateConfig dateConfig = new DateConfig();
            dateConfig.Id = 179;
            dateConfig.DateDuration = Google.Protobuf.WellKnownTypes.Duration.FromTimeSpan(TimeSpan.FromSeconds(5));
            // 注意这里的时间是utc时间
            dateConfig.DateTimestamp = Timestamp.FromDateTime(DateTime.UtcNow);

            await _fieldRpcClient.DateConfigServiceAsync(dateConfig);
            MessageBox();
        }

        // 字节
        private async void BtnByteconfig_Click(object sender, RoutedEventArgs e)
        {
            // 字节
            ByteConfig byteConfig = new ByteConfig();

            byteConfig.Id = 9854564654654;
            byteConfig.PositionBytes = ByteString.CopyFrom(Encoding.UTF8.GetBytes("庄这人的南的很"));

            await _fieldRpcClient.ByteConfigServiceAsync(byteConfig);

            MessageBox();
        }

        // null
        private async void BtnNullconfig_Click(object sender, RoutedEventArgs e)
        {

            // null
            NullConfig nullConfig = new NullConfig();
            nullConfig.Id = 1854564654654;
            nullConfig.NullBool = true;
            nullConfig.NullFloat = null;
            nullConfig.NullUInt = null;
            nullConfig.NullInt = 15;
            nullConfig.NullLong = 112345451234787;

            await _fieldRpcClient.NullConfigServiceAsync(nullConfig);

            MessageBox();
        }

        // list
        private async void BtnListconfig_Click(object sender, RoutedEventArgs e)
        {
            // ListConfig
            ListConfig listConfig = new ListConfig();
            var attributes = new Dictionary<int, string>
            {
                [1] = "one",
                [2] = "two",
                [3] = "three",
                [4] = "four",
                [5] = "five"
            };

            listConfig.Id = 123456456;
            listConfig.Attributes.Add(attributes);

            var dicDetail = new Dictionary<int, ListDetailConfig>
            {
                [1] = new ListDetailConfig { Height = 1, Name = "one" },
                [2] = new ListDetailConfig { Height = 2, Name = "two" },
                [3] = new ListDetailConfig { Height = 3, Name = "three" },
                [4] = new ListDetailConfig { Height = 4, Name = "four" },
                [5] = new ListDetailConfig { Height = 5, Name = "five" }
            };

            listConfig.DicDetail.Add(dicDetail);

            listConfig.Details.Add(new ListDetailConfig { Height = 8, Name = "Eight" });

            var detailConfigs = new List<ListDetailConfig>
            {
               new ListDetailConfig { Height=9,Name="nine"},
               new ListDetailConfig{ Height=10,Name="ten"}
            };

            listConfig.Details.Add(detailConfigs);


            await _fieldRpcClient.ListConfigServiceAsync(listConfig);

            MessageBox();
        }

        // any
        private async void BtnAnyconfig_Click(object sender, RoutedEventArgs e)
        {
            // Any
            AnyConfig anyConfig = new AnyConfig();
            anyConfig.Id = 42564134;

            anyConfig.AnyObject = Any.Pack(new B { Id = 15 });

            await _fieldRpcClient.AnyConfigServiceAsync(anyConfig);
            
            MessageBox();
        }

        // Oneof
        private async void BtnOneofconfig_Click(object sender, RoutedEventArgs e)
        {

            // Oneof
            OneofConfig oneofConfig = new OneofConfig();
            oneofConfig.OA = new A { Id = 1 };
            //oneofConfig.OC = new C { Id = 2 };

            await _fieldRpcClient.OneofConfigServiceAsync(oneofConfig);
            
            MessageBox();
        }


        private void MessageBox()
        {
            string messageBoxText = "执行完成";
            string caption = "HELLO";
            MessageBoxButton button = MessageBoxButton.OK;
            MessageBoxImage icon = MessageBoxImage.Information;
            MessageBoxResult result = System.Windows.MessageBox.Show(messageBoxText, caption, button, icon);
        }
    }

四、执行效果展示

客户端:

 服务端:

 五、源码地址

链接:https://pan.baidu.com/s/1FQY7QOgF8Y90igKV56Yupg 
提取码:mbyg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/890388.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CS5523规格书|MIPI转EDP方案设计|替代LT8911芯片电路原理|ASL集睿致远CS替代龙讯

ASL芯片&#xff08;集睿致远&#xff09; CS5523是一款MIPI DSI输入&#xff0c;DP/e DP输出转换芯片&#xff0c;可pin to pin替代LT8911龙讯芯片。 MIPI DSI 最多支持 4 个通道&#xff0c;每个通道的最大运行速度为 1.5Gps。对于DP 1.2输出&#xff0c;它支持1.62Gbps和2.…

一文揭露AI聊天机器人到底是怎么实现自助应答的

现在很多的企业都会使用客服系统&#xff0c;主要是想通过它们来解决企业的一些问题和需求。所有就衍生了——AI聊天机器人这个新工具&#xff0c;它是把AI人工智能运用到客户服务当中&#xff0c;让AI来帮助我们完成一些解答客户问题的操作。下面我们就来说一下AI聊天机器人是…

创建和使用分区

创建和使用分区 创建一个名为 /home/curtis/ansible/partition.yml 的 playbook&#xff1a; 该palybook包含一个paly&#xff0c;该paly在balancers主机组的主机上运行&#xff1a; 在设备vdb上创建单个主分区&#xff0c;编号为1&#xff0c;大小为1500MiB 使用ext4文件系统…

数据建模和设计for CDGP第五章——如何绘制鸭掌图

CDGP中第五章必考一个数据模型设计题&#xff0c;分值10分。 主要考点 1、围绕一个场景如&#xff08;外卖送餐、图书馆管理系统等&#xff09;进行关系型逻辑数据模型设计2、要求满足范式化&#xff08;通常为3NF&#xff09;3、突出重点的实体并描述实体间的关系 加gzh“大数…

Linux下gdb调试

1.基本命令操作 2.调试方式启动运行无参程序 以下是linux下GDB调试的一个实例&#xff0c;先给出一个示例用的小程序&#xff0c;C语言代码&#xff1a; main.c #include <stdio.h>void Print(int i){printf("hello,程序猿编码 %d\n", i); }int main(int argc…

1281. 整数的各位积和之差

诸神缄默不语-个人CSDN博文目录 力扣刷题笔记 文章目录 1. 简单粗暴的遍历2. 其实也是遍历&#xff0c;但是用Python内置函数只用写一行 1. 简单粗暴的遍历 Python版&#xff1a; class Solution:def subtractProductAndSum(self, n: int) -> int:he0ji1while n>1:last…

杭电比赛总结

我们的队伍&#xff1a;team013 另外两队&#xff1a;team014、team015 ​ 今天是我第一次打杭电&#xff0c;发现杭电多数都是猜结论题 先给一下我们的提交数据 Submit TimeProblem IDTimeMemoryJudge Status4:59:59101115 MS1692 KWrong Answer4:59:55101115 MS1684 KWrong…

互联网发展历程:畅通无阻,流控的智慧应对

随着互联网的蓬勃发展&#xff0c;网络使用量不断增加&#xff0c;可能导致网络拥挤问题。在这个数字化时代&#xff0c;人们需要寻找一种方法来优化网络使用&#xff0c;确保数据的流畅传输。而在这一背景下&#xff0c;流量控制&#xff08;流控&#xff09;应运而生。 网络拥…

如何使用SpringBoot 自定义转换器

&#x1f600;前言 本篇博文是关于SpringBoot 自定义转换器的使用&#xff0c;希望你能够喜欢&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的…

Android Studio实现解析HTML获取图片URL,将URL存到list,进行瀑布流展示

目录 效果展示build.gradle(app)添加的依赖(用不上的可以不加)AndroidManifest.xml错误代码activity_main.xmlitem_image.xmlMainActivityImage适配器ImageModel 接收图片URL效果展示 build.gradle(app)添加的依赖(用不上的可以不加) dependencies {implementation co…

TRT8系列—— 版本差异注意事项

TRT8 一个大版本&#xff0c;8.4-、 8.5、 8.6&#xff08;包含预览功能&#xff09;却有很多变动&#xff0c;一不注意就发现很混乱&#xff0c;特备注此贴。建议具体case可以参考这个合集&#xff0c;真心安利&#xff1a;https://github.com/NVIDIA/trt-samples-for-hackath…

VirtualBox移动虚拟机存储位置,给C盘瘦身

不知不觉&#xff0c;五月份买的电脑的C盘突然要爆了。 我也搞不懂我的软件明明都放在D盘&#xff0c;C盘还是那么满。直到我看到了之前VirtualBox的一些东西。好家伙&#xff0c;直接干了我快30G了。 所以&#xff0c;我在想能不能将这些东西移到D盘&#xff0c;同时也不影响我…

android framework-Pixel3真机系统内置第三方apk实战

一、在/packages/apps创建独一无二的文件夹TestCamera 二、拷贝第三方应用到TestCamera文件夹下 三、创建Android.mk LOCAL_PATH: $(call my-dir)include $(CLEAR_VARS) # Module name should match apk name to be installed LOCAL_MODULE : TestCamera LOCAL_MODULE_TAGS : o…

scrollIntoView 导致整个页面上移问题

更改参数 block: ‘start’, behavior: smooth’更改为 behavior: ‘smooth’, block: ‘nearest’, inline: ‘start’ 在这里插入图片描述

JVM---jvm里的内存溢出

目录 堆溢出 虚拟机栈和本地方法栈溢出&#xff08;栈溢出很少出现&#xff09; 方法区和运行时常量池溢出 本机内存直接溢出&#xff08;实际中很少出现、了解即可&#xff09; 堆溢出 堆溢出&#xff1a;最常见的是大list&#xff0c;list里面有很多元素 堆溢出该怎么解决…

棋牌的逆向工程

前言 之前有些朋友都找我做棋牌的逆向工程 一来就说什么透视啥的 我只能让你早点洗洗睡 不过话说回来 棋牌逆向的思路也是有很多的 例如撞库 溢出 透视吧也能实现不过难度可想而知 透视有些棋牌是可以 不过只能看手里自己的牌例如炸金花 没开牌的时候内存中可能会存放当前的牌…

第四章nginx组件精讲

nginx配件location匹配的规则和优先级&#xff08;重点面试题&#xff09; RUI&#xff1a;统一资源标识符&#xff0c;是一种字符串标识&#xff0c;用于标识抽象的或者物理资源&#xff08;文件&#xff0c;图片&#xff0c;视频&#xff09; nginx当中&#xff1a;uri ww…

可变形卷积(DCN)——论文及代码详解

文章目录 论文详解Deformable ConvolutionDeformable RoI PoolingDeformable ConvNetsUnderstanding Deformable ConvNets 代码详解 论文&#xff1a;《Deformable Convolutional Networks》 论文详解 Deformable Convolution 普通卷积的数学表达 普通的二维卷积包括两个步骤:…

mysql 数据备份和恢复

操作系统&#xff1a;22.04.1-Ubuntu mysql 版本&#xff1a;8.033 binlog 介绍 binlog 是mysql 二进制日志 binary log的简称&#xff0c;可以简单理解为数据的修改记录。 需要开启binlog,才会产生文件&#xff0c;mysql 8.0 默认开启,开启后可以在 /var/lib/mysql &#xff…