第二節:框架前期準備篇之AutoFac常見用法總結

来源:https://www.cnblogs.com/yaopengfei/archive/2018/08/21/9479268.html
-Advertisement-
Play Games

一. 說在前面的話 凡是大約工作在兩年以上的朋友們,或多或少都會接觸到一些框架搭建方面的知識,只要一談到框架搭建這個問題或者最佳用法這個問題,勢必會引起一點點小小的風波,我說我的好,他說他的好,非常容易罵架,所以在本節乃至該系列我僅僅是總結了一下自己日常中的一些用法,談一下自己淺陋的見解,談不上最佳 ...


一. 說在前面的話

  凡是大約工作在兩年以上的朋友們,或多或少都會接觸到一些框架搭建方面的知識,只要一談到框架搭建這個問題或者最佳用法這個問題,勢必會引起一點點小小的風波,我說我的好,他說他的好,非常容易罵架,所以在本節乃至該系列我僅僅是總結了一下自己日常中的一些用法,談一下自己淺陋的見解,談不上最佳,只要不誤導新手 能有點幫助作用就可以了,如您不喜歡,請“右上角  謝謝”。   在框架搭建過程中,在層與層的解耦方面,勢必會涉及到IOC框架,.Net 平臺下我用過的IOC框架主要是: Spring.Net 、Unity、AutoFac,當然還有Castle(我沒用過,就不發表任何評論了), 在用過的IOC框架中,Spring.Net 相對很老了,貌似在2015年就不在更新了,但基本的功能也夠用了。 現階段用的最多的就是Unity和AutoFac了,版本更新也比較快,Unity大約一年前寫過兩篇文章了,本次在該框架系列也會考慮更新一下Unity,本節主要介紹一下AutoFac的幾個基本用法。
  先說一下兩個概念IOC和DI,我的理解:   ① IOC:調用者不再創建(不自己new)被調用者的實例,而是交給容器去創建(AutoFac就充當這裡的容器),這就是控制反轉。   ② DI:容器創建好的實例再註入調用者的過程,就是依賴註入(比如:屬性註入、構造函數註入等)。 AutoFac的信息:   ① 官網地址:https://autofac.org/   ② 官方文檔:http://autofac.readthedocs.io/en/latest/index.html   ③ 最新版本:4.8.1 (截止2018-08-21)

  本節的內容主要包括:

    1. 在使用IOC框架之前的幾種創建對象的方式。

    2. AutoFac的基本用法和幾種生命周期。

    3. AutoFac和Asp.Net MVC5進行整合,利用屬性的方式進行註入。

事先說明一下本節要用到的實現類和介面類:

(1). Ypf.BLL層中包括:CatBLL、DogBLL、RoleBLL、UserBLL。

1   public class CatBLL : IAnimalBLL
2     {
3         public string Introduce()
4         {
5             return "我是貓";
6         }
7     }
CatBLL
1   public class DogBLL : IAnimalBLL
2     {
3         public string Introduce()
4         {
5             return "我是狗";
6         }
7     }
DogBLL
 1   public class RoleBLL : IRoleBLL
 2     {
 3 
 4         public IUserBLL userBLL { get; set; }
 5 
 6         /// <summary>
 7         /// 展示角色信息
 8         /// </summary>
 9         /// <returns></returns>
10         public string ShowRoleInfor()
11         {
12             return "我是管理員角色";
13         }
14 
15 
16         public string ShowDIDemo()
17         {
18             return "哈哈:" + userBLL.GetUserInfor();
19         }
20 
21     }
RoleBLL
 1  public class UserBLL : IUserBLL,IPeopleBLL
 2     {
 3         /// <summary>
 4         /// 獲取用戶信息
 5         /// </summary>
 6         /// <returns></returns>
 7         public string GetUserInfor()
 8         {
 9             return "我是獲取用戶信息的方法";
10         }
11 
12         /// <summary>
13         /// 自我介紹
14         /// </summary>
15         /// <returns></returns>
16         public string Introduce()
17         {
18             return "我是ypf";
19         }
20     }
UserBLL

(2). Ypf.IBLL層包括:IAnimalBLL、IPeopleBLL、IRoleBLL、IUserBLL。

1  public interface IAnimalBLL
2     {
3         string Introduce();
4     }
IAnimalBLL
1  public interface IPeopleBLL
2     {
3         //自我介紹
4         string Introduce();
5     }
IPeopleBLL
1   public interface IRoleBLL
2     {
3         string ShowRoleInfor();
4 
5         string ShowDIDemo();
6 
7     }
IRoleBLL
1  public interface IUserBLL
2     {
3         string GetUserInfor();
4     }
IUserBLL

 

二. 引入IOC框架之前的幾個寫法

1. 最原始的方式直接new(需添加對BLL層的引用)

1 {
2    UserBLL userBll = new UserBLL();
3    var result1 = userBll.GetUserInfor();
4    Console.WriteLine(result1);
5 }

 

2. 面向介面編程(仍需添加對BLL層的引用)

1   {
2      IUserBLL userBll = new UserBLL();
3      var result1 = userBll.GetUserInfor();
4      Console.WriteLine(result1);
5   }

 

3. 介面+反射(只需將BLL層的程式集拷貝進來)

 1 {
 2   Assembly ass = Assembly.Load("Ypf.BLL");
 3   Type type = ass.GetType("Ypf.BLL.UserBLL");
 4   //調用預設的無參構造函數進行對象的創建
 5   object myUserBLL = Activator.CreateInstance(type);
 6   IUserBLL userBLL = (IUserBLL)myUserBLL;
 7   var result1 = userBLL.GetUserInfor();
 8   Console.WriteLine(result1);
 9 
10 }

 

4. 手寫IOC(反射+簡單工廠+配置文件)【需將BLL層的程式集拷貝進來】

 配置文件代碼:

  <appSettings>
    <!--直接修改配置文件,可以切換IUserBLL的實現類,發佈後可以直接通過改配置文件,代碼什麼也不用改,體會:反射+面向介面編程-->
    <add key="DllName" value="Ypf.BLL"/>
    <add key="ClassName" value="Ypf.BLL.UserBLL"/>
  </appSettings>

簡單工廠代碼:

 1     /// <summary>
 2     /// 簡單工廠,隔離對象的創建
 3     /// </summary>
 4    public class SimpleFactory
 5     {
 6         private static string DllName = ConfigurationManager.AppSettings["DllName"];
 7         private static string ClassName = ConfigurationManager.AppSettings["ClassName"];
 8         public static IUserBLL CreateInstance()
 9         {
10             Assembly ass = Assembly.Load(DllName);
11             Type type = ass.GetType(ClassName);
12             object obj = Activator.CreateInstance(type);
13             return (IUserBLL)obj;
14         }
15     }

調用代碼:

1 {
2       IUserBLL userBLL = SimpleFactory.CreateInstance();
3       var result = userBLL.GetUserInfor();
4       Console.WriteLine(result);
5 }

 

三. AutoFac常見用法總結

1. 基本用法

   同時添加對Ypf.BLL層和Ypf.IBLL層的引用,然後 聲明容器→註冊實例→解析對象→調用方法、進行測試,代碼如下:

1  {
2      ContainerBuilder builder = new ContainerBuilder();
3      //把UserBLL註冊為IUserBLL實現類,當請求IUserBLL介面的時候,返回UserBLL對象
4      builder.RegisterType<UserBLL>().As<IUserBLL>();
5      IContainer resolver = builder.Build();
6      IUserBLL userBLL = resolver.Resolve<IUserBLL>();
7      var result1 = userBLL.GetUserInfor();
8      Console.WriteLine(result1);
9 }

  評價:這種用法單純的是為了介紹AutoFac中的幾個方法,僅此而已,在實際開發沒有這麼用的,坑比用法,起不到任何解耦的作用。

 

2. AsImplementedInterfaces的用法

   在很多情況下,一個類可能實現了多個介面, 如果我們通過  builder.RegisterType<xxxBLL>().As<IxxxBLL>(); 這種方式按部就班排著把這個類註冊給每個介面,實現幾個介面,就要寫幾行註冊代碼,很繁瑣,我們可以通過 AsImplementedInterfaces() 方法,可以把一個類註冊給它實現的全部介面。

   這樣的話,想用哪個介面,通過Resolve解析即可,代碼如下:

 1 {
 2      ContainerBuilder builder = new ContainerBuilder();
 3      //這樣請求UserBLL實現的任何介面的時候都會返回 UserBLL 對象。
 4      builder.RegisterType<UserBLL>().AsImplementedInterfaces();
 5      IContainer resolver = builder.Build();
 6      IUserBLL iUserBLL = resolver.Resolve<IUserBLL>();
 7      IPeopleBLL iPeopleBLL = resolver.Resolve<IPeopleBLL>();
 8 
 9      var r1 = iUserBLL.GetUserInfor();
10      var r2 = iPeopleBLL.Introduce();
11 
12      Console.WriteLine(r1);
13      Console.WriteLine(r2);
14 }

  評價:同時添加對Ypf.BLL層和Ypf.IBLL層的引用,這裡也是單純的為了介紹AsImplementedInterfaces()的用法,還是存在實現類的身影,在實際開發中沒有這麼用的,起不到任何解耦的作用,坑比用法。

 

3. AutoFac+反射(徹底消滅實現類)

  引入反射的背景:前面兩種方式都需要添加對Ypf.BLL層的引用,麻煩的要死,根本沒有什麼改觀,還是緊耦合在一起。並且如果有很多介面和實現類的話,用RegisterType一行一行的去寫,累個半死,在這種情況下引入反射的概念,簡化代碼量,代碼如下:

 1  {
 2       ContainerBuilder builder = new ContainerBuilder();
 3       //載入實現類的程式集
 4       Assembly asm = Assembly.Load("Ypf.BLL");
 5       builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces();
 6       IContainer resolver = builder.Build();
 7 
 8       IUserBLL userBLL = resolver.Resolve<IUserBLL>();
 9       IPeopleBLL peopleBLL = resolver.Resolve<IPeopleBLL>();
10       var r1 = userBLL.GetUserInfor();
11       var r2 = peopleBLL.Introduce();
12 
13       Console.WriteLine(r1);
14       Console.WriteLine(r2);
15 }

  評價:徹底擺脫了實現類的身影,與Ypf.BLL層進行瞭解耦,只需要添加對Ypf.IBLL層的引用,但需要把Ypf.BLL的程式集拷貝到AutoFacTest項目下。

小小的升級一下:

   把反射那個程式集類寫到配置文件中,然後在代碼中通過讀取配置文件進行進一步的反射,代碼如下:

1  <appSettings>
2     <add key="DllName" value="Ypf.BLL"/>
3   </appSettings>
 1  {
 2      ContainerBuilder builder = new ContainerBuilder();
 3      //載入實現類的程式集
 4     string DllName = ConfigurationManager.AppSettings["DllName"];
 5     Assembly asm = Assembly.Load(DllName);
 6     builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces();
 7     IContainer resolver = builder.Build();
 8 
 9     IUserBLL userBLL = resolver.Resolve<IUserBLL>();
10     IPeopleBLL peopleBLL = resolver.Resolve<IPeopleBLL>();
11     var r1 = userBLL.GetUserInfor();
12     var r2 = peopleBLL.Introduce();
13 
14     Console.WriteLine(r1);
15     Console.WriteLine(r2);
16 }

 

4. PropertiesAutowired(屬性的自動註入)

  背景:一個實現類中定義了其他類型的介面屬性,比如RoleBLL中定義IUserBLL的介面屬性,而且要對其進行調用, 這個時候就需要通過PropertiesAutowired實現屬性的自動註入了。

  註:只有通過AutoFac創建的對象才能實現屬性的自動註入!! 相關的類、介面要是public類型。

 1  public class RoleBLL : IRoleBLL
 2     {
 3 
 4         public IUserBLL userBLL { get; set; }
 5 
 6         /// <summary>
 7         /// 展示角色信息
 8         /// </summary>
 9         /// <returns></returns>
10         public string ShowRoleInfor()
11         {
12             return "我是管理員角色";
13         }
14 
15 
16         public string ShowDIDemo()
17         {
18             return "哈哈:" + userBLL.GetUserInfor();
19         }
20 
21 
22 
23     }
RoleBLL
 1 {
 2      ContainerBuilder builder = new ContainerBuilder();
 3      //載入實現類的程式集
 4      Assembly asm = Assembly.Load("Ypf.BLL");
 5      builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired();
 6      IContainer resolver = builder.Build();
 7 
 8      IRoleBLL iRoleBLL = resolver.Resolve<IRoleBLL>();
 9      var r1 = iRoleBLL.ShowDIDemo();
10      Console.WriteLine(r1);
}

  下麵測試一下不是AutoFac創建的對象能否實現屬性的自動註入,新建TempTest類,在裡面聲明IUserBLL屬性,並且在方法中進行調用,然後new一個TempTest對象,對該showMsg方法進行調用,發現報空指針錯誤,說明userBLL屬性為空,沒能自動註入。

1  public class TempTest
2     {
3         public IUserBLL userBLL { get; set; }
4 
5         public void showMsg()
6         {
7             Console.WriteLine(userBLL.GetUserInfor());
8         }
9     }
1 //測試自己new的對象不能實現屬性的自動註入
2 //下麵代碼報空指針錯誤
3 {
4      TempTest t = new TempTest();
5      t.showMsg();
6 }

 

5. 1個介面多個實現類的情況

  背景:1個介面有多個實現類的情況(DogBLL 和 CatBLL 都實現了 IAnimalBLL介面)

  分析:resolver.Resolve<IAnimalBLL>();只會返回其中一個類的對象

  解決方案:如果想返回多個實現類的對象,改成 resolver.Resolve<IEnumerable<IAnimalBLL>>()即可。

 1             {
 2                 ContainerBuilder builder = new ContainerBuilder();
 3                 //載入實現類的程式集
 4                 Assembly asm = Assembly.Load("Ypf.BLL");
 5                 builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired();
 6                 IContainer resolver = builder.Build();
 7 
 8                 //返回 CalBLL 和 DogBLL 中的一個
 9                 //{
10                 //    IAnimalBLL iAnimalBLL = resolver.Resolve<IAnimalBLL>();
11                 //    var r1 = iAnimalBLL.Introduce();
12                 //    Console.WriteLine(r1);
13                 //}
14 
15                 //如何獲取多個呢?
16                 {
17                     IEnumerable<IAnimalBLL> blls = resolver.Resolve<IEnumerable<IAnimalBLL>>();
18                     foreach (IAnimalBLL animalBLL in blls)
19                     {
20                         Console.WriteLine(animalBLL.GetType());
21                         Console.WriteLine(animalBLL.Introduce());
22                     }
23                 }
24             }

 

6. AutoFac的幾種常見生命周期

1. InstancePerDependency:每次請求 Resovle都返回一個新對象。InstancePerDependency()【這也是預設的創建實例的方式。】

2. SingleInstance: 單例,只有在第一次請求的時候創建 。SingleInstance()

3. InstancePerRequest:ASP.Net MVC 專用,每次http請求內一個對象(也可以理解為一個方法內)。InstancePerRequest() 和 CallContext神似

4. InstancePerLifetimeScope:在一個生命周期域中,每一個依賴或調用創建一個單一的共用的實例,且每一個不同的生命周期域,實例是唯一的,不共用的。

 下麵測試一下前兩種生命周期

 情況1

 1   {
 2     ContainerBuilder builder = new ContainerBuilder();
 3     //載入實現類的程式集
 4     Assembly asm = Assembly.Load("Ypf.BLL");
 5     builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired().InstancePerDependency();
 6     IContainer resolver = builder.Build();
 7 
 8     IUserBLL u1 = resolver.Resolve<IUserBLL>();
 9     IUserBLL u2 = resolver.Resolve<IUserBLL>();
10 
11     Console.WriteLine(object.ReferenceEquals(u1, u2));
12 
13  }

結果:False,證明InstancePerDependency 每次都創建一個新對象

情況2

 1   {
 2      ContainerBuilder builder = new ContainerBuilder();
 3      //載入實現類的程式集
 4      Assembly asm = Assembly.Load("Ypf.BLL");
 5      builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().PropertiesAutowired().SingleInstance();
 6      IContainer resolver = builder.Build();
 7 
 8      IUserBLL u1 = resolver.Resolve<IUserBLL>();
 9      IUserBLL u2 = resolver.Resolve<IUserBLL>();
10 
11      Console.WriteLine(object.ReferenceEquals(u1, u2));
12 
13 }

結果:true,證明SingleInstance 每次都返回同一個對象。

 

四. AutoFac與MVC整合

1. Controller中通過屬性註入對象

 步驟1:在Ypf.MVC層中添加對Ypf.IBLL層的引用,並將Ypf.BLL的程式集拷貝到 Ypf.MVC中,或者直接改一下Ypf.BLL輸出路徑。

 步驟2:通過Nuget安裝程式集 Autofac.Mvc5。

 步驟3:在Gloabl 註冊 AutoFac代碼。

 1  public class MvcApplication : System.Web.HttpApplication
 2     {
 3         protected void Application_Start()
 4         {
 5             AreaRegistration.RegisterAllAreas();
 6             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
 7             RouteConfig.RegisterRoutes(RouteTable.Routes);
 8             BundleConfig.RegisterBundles(BundleTable.Bundles);
 9 
10             /***********下麵是AutoFac的註冊*************/
11             //1. 創建容器
12             var builder = new ContainerBuilder();
13             //2. 把當前程式集中的所有Controller都註冊進來
14             builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
15             //3. 把Ypf.BLL中的所有類註冊給它的全部實現介面,並且把實現類中的屬性也進行註冊
16             //{ Assembly asmService = Assembly.Load("Ypf.BLL"); }
17             //PS:這裡可以配合配置文件的,將Ypf.BLL寫到配置文件中
18             string DllName = ConfigurationManager.AppSettings["DllName"];
19             Assembly asmService = Assembly.Load(DllName);
20             builder.RegisterAssemblyTypes(asmService).Where(t => !t.IsAbstract).AsImplementedInterfaces().PropertiesAutowired();
21             var container = builder.Build();
22             //4. 下麵這句話表示當mvc創建controller對象的時候,都是由AutoFac為我們創建Controller對象
23             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
24 
25 
26         }
27     }

步驟4:在Controller中進行調用。

 

2. 普通類中通過代碼獲取對象

  在一個沒有通過AutoFac註冊的普通類中如何獲取介面對象呢,通過DependencyResolver.Current.GetService<IUserBLL>();來獲取。

  代碼如下:

1   public class Utils
2     {
3         public static string Test()
4         {       
5             IUserBLL userBLL = DependencyResolver.Current.GetService<IUserBLL>();
6             return userBLL.GetUserInfor();
7         }
8     }

 

3. 如何在普通類中通過屬性的方式註入對象

需要有兩個條件:

  ①: 這個普通類的創建必須在Global中通過AutoFac來進行註冊。

  ②: 獲取這個類的時候必須通過 DependencyResolver.Current.GetService<IUserBLL>(); 這種方式來獲取。

 在Global文件中註冊該普通類

 

該普通類CommonHelp的獲取必須通過DependencyResolver.Current.GetService<CommonHelp>();方式來獲取。

 

4. 在單獨線程中獲取對象

  比如在Quartz.Net 中,需要通過下麵代碼來獲取。

詳細代碼如下:

 {
                //1.創建作業調度池(Scheduler)
                IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();

                //2.創建一個具體的作業即job (具體的job需要單獨在一個文件中執行)
                var job = JobBuilder.Create<HelloJob>().Build();

                //3.創建並配置一個觸發器即trigger   1s執行一次
                var trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x.WithIntervalInSeconds(1)
                                                                               .RepeatForever()).Build();
                //4.將job和trigger加入到作業調度池中
                scheduler.ScheduleJob(job, trigger);

                //5.開啟調度
                scheduler.Start();
}
 1  public class
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前面ORM模塊我們已經完成了開發,接下來要做的就是對項目代碼進行重構了。因為對底層資料庫操作模塊(db_helper.py)進行了改造,之前項目的介面代碼全都跑不起來了。 在寫ORM模塊時,我們已經對產品介面的分頁查詢、新增、修改、獲取指定產品實體介面已經重構好了,還剩下刪除介面未完成 如果前面代碼 ...
  • 體會 第一次開始學習Python,不知道自己之後能否持續堅持下去。我想不論怎樣只要有時間和就努力堅持。爭取以周為單位按要求完成相應工作量的學習。持續學習,不斷總結和進步。 一、Python安裝 Python的安裝是還是是一件比較麻煩的事情。之前安裝python環境到還比較簡單一些。後面再安裝PyCh ...
  • 1、線程的實現方式 線程有兩種實現方式,分別為繼承Thread、實現Runnable介面。差異性:實現方式避免了類的繼承單一性,且對於多個線程同時訪問同一個資源時更便捷。 (1)繼承Thread class TestThread extends Thread { @Override public v ...
  • 1 from lxml import etree 2 from selenium import webdriver 3 import pymysql 4 5 def Geturl(fullurl):#獲取每個招聘網頁的鏈接 6 browser.get(fullurl) 7 shouye_html_t... ...
  • 開始接觸php,奇怪的是,每次打PHP的時候,都會出現,拍*黃*片,覺得好搞笑 今天聽了一上午的課,老司機講的是,面向對象,世間萬物皆對象~ 以下是上課的筆記,和大家共用,不謝,多練習~ //面向對象 // 1 世間萬物皆對象 //一個人,一個車,一架飛機,一個垃圾桶 一切可見之物都是對象,一切不可 ...
  • 數組左移 i 位 3 種方法 1.臨時數組存儲 先將前 i 個元素用數組存起來 再將後 n - i 個元素左移 i 位 最後將存起來的數組添加到後面去即可 2.通過多次調用左移 1 位的函數 3.翻轉 將待移動的數組以 i 為分隔看成兩段 AB 先將 A 翻轉,再將 B 翻轉 之後將數組整個翻轉 1 ...
  • 目錄: 一、os模塊中關於文件/目錄常用的函數使用方法 二、os.path模塊中關於路徑常用的函數使用方法 三、課時30課後習題及答案 接下來會介紹跟Python的文件相關的一些很有用的模塊。模塊是什麼?其實我們寫的每一個源代碼文件(*.py)都是一個模塊。Python自身帶有非常多使用的模塊。 比 ...
  • 想成為一位合格的Android程式員或者一位Android高級工程師是十分有必要知道Android的框架層的工作原理,要知道其工作原理那麼就需要閱讀Android的源代碼。 想要閱讀Android的源代碼最爽的方式的肯定是自己親手下載編譯。為什麼要閱讀Android源代碼? 第一,面試加分項。第二, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...