C#設計模式學習筆記:(3)抽象工廠模式

来源:https://www.cnblogs.com/atomy/archive/2020/01/14/12172604.html
-Advertisement-
Play Games

本筆記摘抄自:https://www.cnblogs.com/PatrickLiu/p/7596897.html,記錄一下學習過程以備後續查用。 一、引言 接上一篇C#設計模式學習筆記:簡單工廠模式(工廠方法模式前奏篇),通過簡單工廠模式的瞭解,它的缺點就是隨著需求的變化我們要不停地修改工廠里 上一 ...


    本筆記摘抄自:https://www.cnblogs.com/PatrickLiu/p/7596897.html,記錄一下學習過程以備後續查用。

    一、引言

    接上一篇C#設計模式學習筆記:簡單工廠模式(工廠方法模式前奏篇),通過簡單工廠模式的瞭解,它的缺點就是隨著需求的變化我們要不停地修改工廠里

    上一篇文章我們講了工廠方法模式,它是為瞭解決簡單工廠模式所面對的問題:如果我們增加新的產品,工廠類的方法就要修改本身的代碼,增加產品越

多,其邏輯越複雜,同時這樣的修改也不符合開放閉合原則OCP--對增加代碼開放,對修改代碼關閉。為瞭解決簡單工廠的問題,我們引出了工廠方法模式,

通過子類化工廠類,解決了工廠類責任的劃分,使得產品和相應的工廠一一對應,符合了OCP。

    如果我們要設計一套房子,當然我們知道房子是由房頂、地板、窗戶、房門等組成的,先設計一套古典風格的房子,再創建一套現代風格的房子,再創建

一套歐式風格的房子,這麼多套房子,我們該怎麼辦呢?今天我們要講的抽象工廠模式可以很好地解決多套變化的問題。

    二、抽象工廠模式介紹

    抽象工廠模式:英文名稱--Abstract Factory Pattern;分類--創建型。

    2.1、動機(Motivate)

    在軟體系統中,經常面臨著"一系列相互依賴的對象"的創建工作,同時,由於需求的變化,往往存在更多系列對象的創建工作。如何應對這種變化?如何

繞過常規的對象創建方法(new),提供一種"封裝機制"來避免客戶程式和這種"多系列具體對象創建工作"的緊耦合?

    2.2、意圖(Intent)

    提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。——《設計模式》GoF

    2.3、結構圖(Structure)

    該圖是抽象工廠的UML圖,結合抽象工廠的意圖、動機和圖示來理解該模式,今天我們就以建設房子為例來說明抽象工廠的實現機理。

    2.4、模式的組成

    從上圖可以看出,在抽象工廠模式的結構圖有以下角色:

    1)抽象產品類角色(AbstractProduct):為抽象工廠中相互依賴的每種產品定義抽象介面對象,也可以這樣說,有幾種產品,就要聲明幾個抽象角色,

每一個抽象產品角色和一種具體的產品相匹配。

    2)具體產品類(ConcreteProduct):具體產品類實現了抽象產品類,是針對某個具體產品的實現的類型。

    3)抽象工廠類角色(AbstractFactory):定義了創建一組相互依賴的產品對象的介面操作,每種操作和每種產品一一對應。

    4)具體工廠類角色(ConcreteFactory):實現抽象類里所有抽象介面操作,可以創建某系列具體的產品,這些具體的產品是“抽象產品類角色”的子類。

    2.5、抽象工廠的具體代碼實現

    隨著我們年齡的增長,我們也到了結婚的年齡,結婚首要的問題就是房子的問題。假設我有一個很有錢的爸爸(呃,發夢中……),我的哥哥們希望能有

一套歐式風格的房子,再加上田園風光,悠閑自在。而我就不一樣了,我希望有一套現代樣式的房子。由於房子由房頂、地板、窗戶和房門組成(其他組

件暫時省略),每套房子的房頂、地板、窗戶和房門都是一個體系的。

    下麵讓我們看看如何使用抽象工廠模式來實現不同房屋的建造:

    class Program
    {
        /// <summary>
        /// 房頂抽象類,子類的房頂必須繼承該類。
        /// </summary>
        public abstract class Roof
        {
            /// <summary>
            /// 創建房頂
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 地板抽象類,子類的地板必須繼承該類。
        /// </summary>
        public abstract class Floor
        {
            /// <summary>
            /// 創建地板
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 窗戶抽象類,子類的窗戶必須繼承該類。
        /// </summary>
        public abstract class Window
        {
            /// <summary>
            /// 創建窗戶
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 房門抽象類,子類的房門必須繼承該類。
        /// </summary>
        public abstract class Door
        {
            /// <summary>
            /// 創建房門
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 歐式的房頂
        /// </summary>
        public class EuropeanRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("創建歐式的房頂");
            }
        }

        /// <summary>
        /// 歐式的地板
        /// </summary>
        public class EuropeanFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("創建歐式的地板");
            }
        }

        /// <summary>
        ///歐式的窗戶
        /// </summary>
        public class EuropeanWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("創建歐式的窗戶");
            }
        }

        /// <summary>
        /// 歐式的房門
        /// </summary>
        public class EuropeanDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("創建歐式的房門");
            }
        }

        /// <summary>
        /// 現代的房頂
        /// </summary>
        public class ModernizationRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("創建現代的房頂");
            }
        }

        /// <summary>
        /// 現代的地板
        /// </summary>
        public class ModernizationFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("創建現代的地板");
            }
        }

        /// <summary>
        /// 現代的窗戶
        /// </summary>
        public class ModernizationWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("創建現代的窗戶");
            }
        }

        /// <summary>
        /// 現代的房門
        /// </summary>
        public class ModernizationDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("創建現代的房門");
            }
        }

        /// <summary>
        /// 抽象工廠類,提供創建不同類型房子的介面。
        /// </summary>
        public abstract class AbstractFactory
        {
            //抽象工廠提供創建一系列產品的介面,此處給出了房頂、地板、窗戶和房門的創建介面。
            public abstract Roof CreateRoof();
            public abstract Floor CreateFloor();
            public abstract Window CreateWindow();
            public abstract Door CreateDoor();
        }

        /// <summary>
        /// 歐式風格房子的工廠,負責創建歐式風格的房子。
        /// </summary>
        public class EuropeanFactory : AbstractFactory
        {
            //製作歐式房頂
            public override Roof CreateRoof()
            {
                return new EuropeanRoof();
            }

            //製作歐式地板
            public override Floor CreateFloor()
            {
                return new EuropeanFloor();
            }

            //製作歐式窗戶
            public override Window CreateWindow()
            {
                return new EuropeanWindow();
            }

            //製作歐式房門
            public override Door CreateDoor()
            {
                return new EuropeanDoor();
            }
        }

        /// <summary>
        /// 現在風格房子的工廠,負責創建現代風格的房子。
        /// </summary>
        public class ModernizationFactory : AbstractFactory
        {
            //製作現代房頂
            public override Roof CreateRoof()
            {
                return new ModernizationRoof();
            }

            //製作現代地板
            public override Floor CreateFloor()
            {
                return new ModernizationFloor();
            }

            //製作現代窗戶
            public override Window CreateWindow()
            {
                return new ModernizationWindow();
            }

            //製作現代房門
            public override Door CreateDoor()
            {
                return new ModernizationDoor();
            }
        }

        static void Main(string[] args)
        {
            #region 抽象工廠模式
            //歐式風格的房子
            AbstractFactory europeanFactory = new EuropeanFactory();
            europeanFactory.CreateRoof().Create();
            europeanFactory.CreateFloor().Create();
            europeanFactory.CreateWindow().Create();
            europeanFactory.CreateDoor().Create();

            //現代風格的房子
            AbstractFactory modernizationFactory = new ModernizationFactory();
            modernizationFactory.CreateRoof().Create();
            modernizationFactory.CreateFloor().Create();
            modernizationFactory.CreateWindow().Create();
            modernizationFactory.CreateDoor().Create();

            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    2.6、 抽象工廠應對需求變更

    假設我的姐姐一看我們的房子很好,她希望有一套古典風格的房子,怎麼處理呢?

    class Program
    {
        /// <summary>
        /// 房頂抽象類,子類的房頂必須繼承該類。
        /// </summary>
        public abstract class Roof
        {
            /// <summary>
            /// 創建房頂
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 地板抽象類,子類的地板必須繼承該類。
        /// </summary>
        public abstract class Floor
        {
            /// <summary>
            /// 創建地板
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 窗戶抽象類,子類的窗戶必須繼承該類。
        /// </summary>
        public abstract class Window
        {
            /// <summary>
            /// 創建窗戶
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 房門抽象類,子類的房門必須繼承該類。
        /// </summary>
        public abstract class Door
        {
            /// <summary>
            /// 創建房門
            /// </summary>
            public abstract void Create();
        }

        /// <summary>
        /// 歐式的房頂
        /// </summary>
        public class EuropeanRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("創建歐式的房頂");
            }
        }

        /// <summary>
        /// 歐式的地板
        /// </summary>
        public class EuropeanFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("創建歐式的地板");
            }
        }

        /// <summary>
        ///歐式的窗戶
        /// </summary>
        public class EuropeanWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("創建歐式的窗戶");
            }
        }

        /// <summary>
        /// 歐式的房門
        /// </summary>
        public class EuropeanDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("創建歐式的房門");
            }
        }

        /// <summary>
        /// 現代的房頂
        /// </summary>
        public class ModernizationRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("創建現代的房頂");
            }
        }

        /// <summary>
        /// 現代的地板
        /// </summary>
        public class ModernizationFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("創建現代的地板");
            }
        }

        /// <summary>
        /// 現代的窗戶
        /// </summary>
        public class ModernizationWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("創建現代的窗戶");
            }
        }

        /// <summary>
        /// 現代的房門
        /// </summary>
        public class ModernizationDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("創建現代的房門");
            }
        }

        /// <summary>
        ///古典的房頂
        /// </summary>
        public class ClassicalRoof : Roof
        {
            public override void Create()
            {
                Console.WriteLine("創建古典的房頂");
            }
        }

        /// <summary>
        /// 古典的地板
        /// </summary>
        public class ClassicalFloor : Floor
        {
            public override void Create()
            {
                Console.WriteLine("創建古典的地板");
            }
        }

        /// <summary>
        /// 古典的窗戶
        /// </summary>
        public class ClassicalWindow : Window
        {
            public override void Create()
            {
                Console.WriteLine("創建古典的窗戶");
            }
        }

        /// <summary>
        /// 古典的房門
        /// </summary>
        public class ClassicalDoor : Door
        {
            public override void Create()
            {
                Console.WriteLine("創建古典的房門");
            }
        }

        /// <summary>
        /// 抽象工廠類,提供創建不同類型房子的介面。
        /// </summary>
        public abstract class AbstractFactory
        {
            //抽象工廠提供創建一系列產品的介面,此處給出了房頂、地板、窗戶和房門的創建介面。
            public abstract Roof CreateRoof();
            public abstract Floor CreateFloor();
            public abstract Window CreateWindow();
            public abstract Door CreateDoor();
        }

        /// <summary>
        /// 歐式風格房子的工廠,負責創建歐式風格的房子。
        /// </summary>
        public class EuropeanFactory : AbstractFactory
        {
            //製作歐式房頂
            public override Roof CreateRoof()
            {
                return new EuropeanRoof();
            }

            //製作歐式地板
            public override Floor CreateFloor()
            {
                return new EuropeanFloor();
            }

            //製作歐式窗戶
            public override Window CreateWindow()
            {
                return new EuropeanWindow();
            }

            //製作歐式房門
            public override Door CreateDoor()
            {
                return new EuropeanDoor();
            }
        }

        /// <summary>
        /// 現在風格房子的工廠,負責創建現代風格的房子。
        /// </summary>
        public class ModernizationFactory : AbstractFactory
        {
            //製作現代房頂
            public override Roof CreateRoof()
            {
                return new ModernizationRoof();
            }

            //製作現代地板
            public override Floor CreateFloor()
            {
                return new ModernizationFloor();
            }

            //製作現代窗戶
            public override Window CreateWindow()
            {
                return new ModernizationWindow();
            }

            //製作現代房門
            public override Door CreateDoor()
            {
                return new ModernizationDoor();
            }
        }

        /// <summary>
        /// 古典風格房子的工廠,負責創建古典風格的房子。
        /// </summary>
        public class ClassicalFactory : AbstractFactory
        {
            //創建古典房頂
            public override Roof CreateRoof()
            {
                return new ClassicalRoof();
            }

            //創建古典地板
            public override Floor CreateFloor()
            {
                return new ClassicalFloor();
            }

            //創建古典窗戶
            public override Window CreateWindow()
            {
                return new ClassicalWindow();
            }

            //創建古典房門
            public override Door CreateDoor()
            {
                return new ClassicalDoor();
            }
        }

        static void Main(string[] args)
        {
            #region 抽象工廠模式
            //歐式風格的房子
            AbstractFactory europeanFactory = new EuropeanFactory();
            europeanFactory.CreateRoof().Create();
            europeanFactory.CreateFloor().Create();
            europeanFactory.CreateWindow().Create();
            europeanFactory.CreateDoor().Create();

            //現代風格的房子
            AbstractFactory modernizationFactory = new ModernizationFactory();
            modernizationFactory.CreateRoof().Create();
            modernizationFactory.CreateFloor().Create();
            modernizationFactory.CreateWindow().Create();
            modernizationFactory.CreateDoor().Create();

            //古典風格的房子
            AbstractFactory classicalFactory = new ClassicalFactory();
            classicalFactory.CreateRoof().Create();
            classicalFactory.CreateFloor().Create();
            classicalFactory.CreateWindow().Create();
            classicalFactory.CreateDoor().Create();

            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    從上面代碼可以看出,需要添加5個類:4個類分別創建古典風格的房頂、地板、窗戶和房門的具體產品,另外一個是古典風格房子的工廠類,負責創建

古典風格的房子。

    從上面代碼可以看出,抽象工廠對於系列產品的變化支持開閉原則(對擴展開放,對修改封閉),擴展起來非常簡便。但是,抽象工廠對於增加新產品

這種情況就不支持開閉原則,因為要修改創建系列產品的抽象基類AbstractFactory,增加相應產品的創建方法,這也是抽象工廠的缺點所在。

    三、抽象工廠的實現要點

    1)如果沒有應對“多系列對象創建”的需求變化,則沒有必要使用AbstractFactory模式,這時候使用簡單工廠模式完全可以。

    2)"系列對象"指的是這些對象之間有相互依賴、或作用的關係,例如游戲開發場景中“道路”與“房屋”的依賴,“道路”與“地道”的依賴。

    3)AbstractFactory模式主要在於應對“新系列”的需求變動,其缺點在於難以應對“新對象”的需求變動

    4)AbstractFactory模式經常和FactoryMethod模式共同組合來應對“對象創建”的需求變化。

    3.1抽象工廠模式的優點

    抽象工廠模式將系列產品的創建工作延遲到具體工廠的子類中,我們聲明工廠類變數的時候使用的是抽象類型,同理,我們使用產品類型也是抽象類型,

這樣做可以儘可能地減少客戶端代碼與具體產品類之間的依賴,從而降低了系統的耦合度。耦合度降低了,對於後期的維護和擴展就更有利,這就是抽象

工廠模式的優點所在。

    可能有人會說在Main方法裡面(客戶端)還是會使用具體的工廠類,對的。這個其實我們可以通過.Net配置文件把這部分移出去,把依賴關係放到配置文

件中。如果有新的需求我們只需要修改配置文件,根本就不需要修改代碼了,讓客戶代碼更穩定。依賴關係肯定會存在,我們要做的就是降低依賴,想完全

去除很難,也不現實。

    3.2抽象工廠模式的缺點

    有優點肯定就有缺點,因為每種模式都有它的使用範圍,或者說不能解決的問題就是缺點。抽象工廠模式很難支持增加新產品的變化,這是因為抽象工廠

介面中已經確定了可以被創建的產品集合,如果需要添加新產品,此時就必須去修改抽象工廠的介面,這樣就涉及到抽象工廠類以及所有子類的改變,這樣

也就違背了開閉原則。

    3.3抽象工廠模式的使用場景

    如果系統需要多套的代碼解決方案,並且每套的代碼方案中又有很多相互關聯的產品類型,並且在系統中可以相互替換地使用一套產品的時候就可以使用

該模式,客戶端不需要依賴具體實現。

    四、.NET中抽象工廠模式實現

    微軟的類庫發展了這麼多年,設計模式在裡面有大量的應用。抽象工廠模式在.NET類庫中也存在著大量的使用,比如和操作資料庫有關的類型,這個類是

System.Data.Common.DbProviderFactory,此類位於System.Data.dll程式集中。該類扮演抽象工廠模式中抽象工廠的角色,我們可以用ILSpy反編譯工具查

看該類的實現:

    /// 扮演抽象工廠的角色
    /// 創建連接資料庫時所需要的對象集合
    /// 這個對象集合包括有DbConnection對象(抽象產品類)、DbCommand類、DbDataAdapter類,針對不同的具體工廠都需要實現該抽象類中的方法。

    public abstract class DbProviderFactory
    {
        public virtual bool CanCreateDataSourceEnumerator
        {
            get
            {
                return false;
            }
        }

        public virtual DbCommand CreateCommand()
        {
            return null;
        }

        public virtual DbCommandBuilder CreateCommandBuilder()
        {
            return null;
        }

        public virtual DbConnection CreateConnection()
        {
            return null;
        }

        public virtual DbConnectionStringBuilder CreateConnectionStringBuilder()
        {
            return null;
        }

        public virtual DbDataAdapter CreateDataAdapter()
        {
            return null;
        }

        public virtual DbParameter CreateParameter()
        {
            return null;
        }

        public virtual CodeAccessPermission CreatePermission(PermissionState state)
        {
            return null;
        }

        public virtual DbDataSourceEnumerator CreateDataSourceEnumerator()
        {
            return null;
        }
    }
View Code

    DbProviderFactory類是一個抽象工廠類,該類提供了創建資料庫連接時所需要的對象集合的介面,實際創建工作在其子類工廠中進行。微軟使用的是

SQL Server資料庫,因此提供了連接SQL Server數據的具體工廠實現,具體代碼可以用反編譯工具查看。

    SqlClientFactory扮演著具體工廠的角色,用來創建連接SQL Server數據所需要的對象:

    public sealed class SqlClientFactory : DbProviderFactory, IServiceProvider
    {
        public static readonly SqlClientFactory Instance = new SqlClientFactory();

        public override bool CanCreateDataSourceEnumerator
        {
            get
            {
                return true;
            }
        }

        private SqlClientFactory()
        {
        }

        public override DbCommand CreateCommand()
        {
            return new SqlCommand();
        }

        public override DbCommandBuilder CreateCommandBuilder()
        {
            return new SqlCommandBuilder();
        }

        public override DbConnection CreateConnection()
        {
            return new SqlConnection();
        }

        public override DbConnectionStringBuilder CreateConnectionStringBuilder()
        {
            return new SqlConnectionStringBuilder();
        }

        public override DbDataAdapter CreateDataAdapter()
        {
            return new SqlDataAdapter();
        }

        public override DbParameter CreateParameter()
        {
            return new SqlParameter();
        }

        public override CodeAccessPermission CreatePermission(PermissionState state)
        {
            return new SqlClientPermission(state);
        }

        public override DbDataSourceEnumerator CreateDataSourceEnumerator()
        {
            return SqlDataSourceEnumerator.Instance;
        }

        object IServiceProvider.GetService(Type serviceType)
        {
            object result = null;
            if (serviceType == GreenMethods.SystemDataCommonDbProviderServices_Type)
            {
                result = GreenMethods.SystemDataSqlClientSqlProviderServices_Instance();
            }
            return result;
        }
    }
View Code

    OdbcFactory也是具體工廠類:

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 static DataTable ConvertJsonToTable(string jsonValue) 2 { 3 DataTable dt = (DataTable)JsonConvert.DeserializeObject(jsonValue, typeof(DataTable)); 4 ...
  • 本筆記摘抄自:https://www.cnblogs.com/PatrickLiu/p/7614630.html,記錄一下學習過程以備後續查用。 一、引言 在現實生活中,我們經常會遇到一些構成比較複雜的物品。比如電腦,是由CPU、主板、記憶體條、硬碟、顯卡、機箱等組裝而成的。手機也是複雜物品, 由主板 ...
  • 做了一個 項目本地測了沒問題發佈到正式環境上,幾天之後有個統計頁面報錯了,看了本地是正常的, 於是就排查,發現 ID 列 在對 字元串轉int 時候 由於用了 Convert.TonInt16 長度不夠, 資料庫的ID 已經到了33000。 自己也知道 Convert.TonInt16 、 Conv ...
  • 微信公眾號: "Dotnet9" ,網站: "Dotnet9" ,問題或建議: "請網站留言" , 如果對您有所幫助: "歡迎贊賞" 。 C WPF之Material Design自定義顏色 閱讀導航 1. 本文背景 2. 代碼實現 3. 本文參考 1. 本文背景 主要介紹使用Material De ...
  • 生活中,如果1+2+3+4.....+100,大家基本上都會用等差數列計算,如果有人從1開始加,不是傻就是白X,那麼程式中呢,是不是也是這樣。今天無意中看到了尾遞歸,以前也寫過,但是不知道這個專業名詞,今天寫一下對比下性能問題。 今天主要是看到了尾遞歸,所以聯想到了這些,寫下這篇文章,其中也把Ben ...
  • 背景 通常,.Net 應用程式中的配置存儲在配置文件中,例如 App.config、Web.config 或 appsettings.json。從 ASP.Net Core 開始,出現了一個新的可擴展配置框架,它允許將配置存儲在配置文件之外,並從命令行、環境變數等等中檢索它們。 在傳統項目中,修改配 ...
  • 前言 導出功能幾乎是所有應用系統必不可少功能,今天我們來談一談,如何使用記憶體映射文件MMF進行記憶體優化,本文重點介紹使用方法,相關原理可以參考文末的連接 實現 我們以單次導出一個excel舉例(csv同理),excel包含1~n個sheet,在每個sheet中存儲的按行和列的坐標在單元格存儲具體數據 ...
  • 最近在處理客戶端安裝程式過程,有一個需求:需要檢測Windows平臺下安裝office 版本信息以及獲取使用的office是32 位還是64 位; 當檢測出office 位數為64位時,提示當前office 不支持程式的使用。 找了很多資料,一般情況下,是不能直接獲取office 安裝位數信息的;加 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...