zoukankan      html  css  js  c++  java
  • .Net Core自定义组件封装,委托的初始化和分派

    在研究Core源码过程中,发现在封装自定义组件时用了很多委托的概念,使代码更加简洁高效

     

    委托目前的使用场景目前分为两个:

    1)扩展自定义组件(委托的初始化)

    2)避免类库之间的循环调用依赖(委托的分派)

    准备工作:

    委托是什么?是一种引用类型,用于将方法作为参数传递给其他方法

    委托简单例子:

     1 //定义委托
     2 private delegate int CaculateDelegate(int x, int y);
     3 static void Main(string[] args)
     4 {
     5     //实例化委托
     6     CaculateDelegate caculateDelegate =new CaculateDelegate(Add);
     7 
     8     //调用委托
     9     Console.WriteLine(caculateDelegate.Invoke(2, 1));
    10 
    11     Console.WriteLine("Hello World!");
    12 
    13     Console.ReadLine();
    14 }
    15 
    16 static int Add(int x, int y)
    17 { 
    18     return x + y;
    19 }
    结果:

    补充Action和Func的委托声明:

     1 //Action声明委托 可接受0-16个传入参数,无返回值
     2 Action<int,int> calaction=new Action<int,int>(Add_Action);
     3 calaction.Invoke(2, 1);
     4 
     5 //Func声明委托 接受0-16个传入参数,必须有返回值
     6 Func<int,int,int> calfun = new Func<int, int,int>(Add);
     7 Console.WriteLine(calfun.Invoke(2, 2));
     8 
     9  //Action声明委托 Lamada表达式
    10 Action<int, int> callamadaaction = ((a, b) => { Console.WriteLine(a + b); });
    11 callamadaaction.Invoke(2, 2);
    12 
    13 //Action参数传递
    14 TestAdd(callamadaaction, 3, 3);
    15 Console.WriteLine("Funcs!");
    16 
    17 
    18 static void TestAdd(Action<int, int> action,int input1,int input2)
    19 {
    20     action(input1, input2);
    21 }

    1)扩展自定义组件-委托初始化

    这里我们以邮件发送功能为例

    增加邮件的扩展方法,AddMyEmailSevice.cs

     1 public static IServiceCollection AddMyEmailSevice(this IServiceCollection services, Action<EmailSettings> configAction)
     2 {
     3 
     4     EmailSettings emailSettings = new EmailSettings();
     5     configAction.Invoke(emailSettings); 
     6     services.AddSingleton<IC2FactoryEmail, C2FactoryEmail>(sp =>
     7                                                            {
     8                                                                return new C2FactoryEmail(emailSettings);
     9                                                            });
    10     return services;
    11 }

    传入参数Action<EmailSettings> configAction. 这里的EmailSettings是邮件配置的Model类。

    在ConfigurationService调用邮件扩展方法,通过Action的Lamada方式初始化EmailSettings的值。在AddMyEmailSevice中,configAction.Invoke触发该初始化方法。

    1 services.AddMyEmailSevice(config => {
    2       config.FromMail= Configuration.GetSection("EmailSetting:FromMail").Value;
    3       config.Authorization = Configuration.GetSection("EmailSetting:Authorization").Value;
    4       config.Emailtype = (EmailType)Enum.Parse(typeof(EmailType), Configuration.GetSection("EmailSetting:Emailtype").Value)  ;
    5       config.IsBodyHtml = Configuration.GetSection("EmailSetting:IsBodyHtml").Value=="true"?true:false;
    6       config.ToMailList = Configuration.GetSection("EmailSetting:ToMailList").Value;
    7   });

    该方法好处是不需要关心是如何初始化,触发Invoke时机可以自己定义

    2)避免类库的循环依赖-委托分派

    如图所示:有两个类库Uni_Common和Uni_FLK

    其中Uni_FLK的UserService登陆时,记录登陆日志,调用LogHelper的AddLog

    1 public void Login(string username, string password)
    2 {
    3     Console.WriteLine("Login Success!");
    4 
    5     LogHelper.AddLog("登陆成功");
    6 }

    LogHelper实现AddLog时,需要引用Uni_FLK中的LogService,这样就造成了循环依赖

    1 public class LogHelper
    2     {
    3         public static void AddLog(string message)
    4         {
    5             //要写入数据库  要引用Uni_FLK中的LogService
    6         } 
    7     }

    通过委托来解决这个问题,在LogHelper中重载AddLog

    public class LogHelper
    {
        public static void AddLog(string message)
        {
            //要写入数据库  要引用Uni_FLK中的LogService
        }
    
        public static void AddLog(string message, Action<string> writeInDB)
        {
            writeInDB(message);
        }
    }

    UserService调用如下:

    1 LogHelper.AddLog("登陆成功", message =>
    2                  {
    3 
    4                      LogService.WriteLogInDB(message);
    5                  });

    运行结果:

    总结:

    了解委托的基本概念和几种使用方式。

    有返回值使用Fun<T>,没有返回值使用Action<T>。

    从对Net Core组件的邮件发送功能进行扩展,使用委托对配置进行初始化。通过委托分派解决类库间循环依赖的问题。

     

    以上,仅用于学习和总结!

  • 相关阅读:
    tp5使用jwt生成token,做api的用户认证
    thinkphp5.0多条件模糊查询以及多条件查询带分页如何保留参数
    tp5.1 模型 where多条件查询 like 查询 --多条件查询坑啊!!(tp5.1与tp5.0初始化控制器不一样)
    获取客户端IP地址-----以及--------线上开启redis扩展
    分享几个免费IP地址查询接口(API)
    thinkphp5选择redis库,让数据存入不同的redis库
    【JZOJ4824】【NOIP2016提高A组集训第1场10.29】配对游戏
    【JZOJ1637】【ZJOI2009】狼和羊的故事
    【JZOJ1611】Dining
    【JZOJ2224】【NOI2006】最大获利
  • 原文地址:https://www.cnblogs.com/ywkcode/p/15764008.html
Copyright © 2011-2022 走看看