C# 嵌入dll 動軟代碼生成器基礎使用 系統緩存全解析 .NET開發中的事務處理大比拼 C#之數據類型學習 【基於EF Core的Code First模式的DotNetCore快速開發框架】完成對D

C# 嵌入dll

 

  在不少時候咱們在生成C#exe文件時,若是在工程裏調用了dll文件時,那麼若是不加以處理的話在生成的exe文件運行時須要連同這個dll一塊兒轉移,相比於一個單獨乾淨的exe,這種形式總歸讓人不爽,那麼有辦法讓生成的軟件中直接就包含這個dll文件嗎,這樣就能夠不用dll跟着exe走了,避免單獨不能運行的狀況。html

        答案是有的!git

        

      在工程項目目錄下找到Resources.resx文件並點擊,而後按下面操做,添加資源,將你要加入的dll添加進來。github

          

      操做完成後,就會在下面的內容框裏看到你添加進來的dll。redis

        

        而後在工程中加入下面這個函數代碼:數據庫

複製代碼
1    System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
2         {
3             string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");
4             dllName = dllName.Replace(".", "_");
5             if (dllName.EndsWith("_resources")) return null;
6             System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
7             byte[] bytes = (byte[])rm.GetObject(dllName);
8             return System.Reflection.Assembly.Load(bytes);
9         }
複製代碼

在InitializeComponent();以前調用。這樣生成的exe就包含這個dll文件啦。c#

複製代碼
1   public Form1()
2         {
3             this.StartPosition = FormStartPosition.CenterScreen;
4             AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
5             InitializeComponent();
6         }
複製代碼

 

 

動軟代碼生成器基礎使用

 

前幾天作項目用到了動軟代碼生成器瀏覽器

對剛出社會的我來講能夠說什麼都不知道,對此趕忙學習了一下才發現這是李天平老師開發的軟件膜拜一下!緩存

以此總結一下安全

1.軟件基本使用服務器

我在百度下載的是V2.78版的

添加服務器 選擇要鏈接的數據庫

點擊鏈接/測試 看是否成功,同時選擇要鏈接的數據庫,否則加載所有庫要等很久的

學習使用呢,下載完成後有在左邊模板管理有一個

 

2.全部對象使用

3.模板生成

這裏直接打開生成會報錯

須要點開模板代碼生成,如下是相應的頁面

 

而後再去點生成模板

 

能夠對相應的字段修改,下面這個是自帶的模板示例 能夠照着這個去寫本身業務邏輯

也能夠點擊批量模板生成

但有一個問題就是生成的文件名都是表名,若是表不少的話就要改不少,咱們用生成器就是爲了節約時間

爲了解決這個問題我寫了WindowsForms 能夠批量修改生成文件的後綴名已達到項目的符合的命名規範

批量修改文件名下載地址:https://files.cnblogs.com/files/yuanzijian-ruiec/%E6%96%87%E4%BB%B6%E5%90%8D%E6%89%B9%E9%87%8F%E4%BF%AE%E6%94%B9.zip

參考原文:https://www.cnblogs.com/ltp/archive/2011/05/25/2057151.html

 

 

   有時候總聽到網友說網站運行好慢,不知如何是好;有時候也總見到一些朋友寫的網站功能看起來很是好,但訪問性能卻極其的差。沒有「勤儉節約」的意識,勢必會形成「鋪張浪費」。如何應對這種狀況,充分利用系統緩存則是首要之道。

     系統緩存有什麼好處呢?舉個簡單的例子,你想經過網頁查詢某些數據,而這些數據並不是實時變化,或者變化的時間是有期限的。例如查詢一些歷史數據。那麼每一個用戶每次查的數據都是同樣的。若是不設置緩存,ASP.NET也會根據每一個用戶的請求重複查詢n次,這就增長了沒必要要的開銷。因此,可能的狀況下儘可能使用緩存,從內存中返回數據的速度始終比去數據庫查的速度快,於是能夠大大提供應用程序的性能。畢竟如今內存很是便宜,用空間換取時間效率應該是很是划算的。尤爲是對耗時比較長的、須要創建網絡連接的數據庫查詢操做等。

緩存功能是大型網站設計一個很重要的部分。由數據庫驅動的Web應用程序,若是須要改善其性能,最好的方法是使用緩存功能。

 

       系統緩存全解析文章索引

15.4.1      緩存的分類

     從分佈上來看,咱們能夠歸納爲客戶端緩存和服務器端緩存。如圖15-1所示:

 

 

 

15-1  緩存的分類

 

客戶端緩存—— 這點你們都有直觀的印象。好比你去一個新的網站,第一次可能要花一陣子時間才能載入整個頁面。而之後再去呢,時間就會大大的縮短,緣由就在於這個客戶端緩存。如今的瀏覽器都比較智能,它會在客戶機器的硬盤上保留許多靜態的文件,好比各類gif,jpeg文件等等。等之後再去的時候,它會盡可能使用本地緩存裏面的文件。只有服務器端的文件更新了,或是緩存裏面的文件過時了,它纔會再次從服務器端下載這些東西。不少時候是IE替咱們作了這件事情。

 

服務器端緩存—— 有些東西無法或是不宜在客戶端緩存,那麼咱們只好在服務器端想一想辦法了。服務器端緩存從性質上看,又能夠分爲兩種。

(1)靜態文件緩存

    好多頁面是靜態的,不多改動,那麼這種文件最適於做靜態緩存。如今的IIS 6.0這部份內容是直接存放在Kernel的內存中,由HTTP.SYS直接管理。因爲它在Kernel Space,因此它的性能很是的高。用戶的請求若是在緩存裏面,那麼HTTP.SYS直接將內容發送到network driver上去,不須要像之前那樣從IIS的User space的內存copy到Kernel中,而後再發送到TCP/IP stack上。Kernel level cache幾乎是如今高性能Web server的一個必不可少的特性。

(2)動態緩存

     動態緩存是比較有難度的。由於你在緩存的時候要時刻注意一個問題,那就是緩存的內容是否是已通過時了。由於內容過期了可能會有很嚴重的後果。好比網上買賣股票的網站。你給別人提供的價格是過期的,那人家非砍了你不可。緩存如何發現本身是否是過期就是一個很是複雜的問題。

 

    在ASP.NET中,常見的動態緩存主要有如下幾種手段:

  Ø  傳統緩存方式

  Ø  頁面輸出緩存。

  Ø  頁面局部緩存。

  Ø  利用.NET提供的System.Web.Caching 緩存。

  Ø  緩存依賴。

 

15.4.2  傳統緩存方式

好比將可重複利用的東西放到Application或是Session中去保存。

 

 Session["Style"] = val;
 Application["Count"] = 0;

 

 

(選自《亮劍.NET:.NET深刻體驗與實戰精要》15章)

 

 

.NET開發中的事務處理大比拼

Posted on 2009-06-17 20:38  李天平 閱讀(5199) 評論(2)  編輯  收藏

事務是一組組合成邏輯工做單元的數據庫操做,在系統執行過程當中可能會出錯,但事務將控制和維護每一個數據庫的一致性和完整性。事務處理的主要特徵是,任務要麼所有完成,要麼都不完成。在寫入一些記錄時,要麼寫入全部記錄,要麼什麼都不寫入。若是在寫入一個記錄時出現了一個失敗,那麼在事務處理中已寫入的其餘數據就會回滾。事務可能由不少單個任務構成。

簡單事務的一個常見例子:把錢從A帳戶轉到B帳戶,這涉及兩項任務,即從A帳戶把錢取出來;把錢存入B帳戶。兩項任務要麼同時成功,要麼一塊兒失敗,給予回滾,以便保持帳戶的狀態和原來相同。不然,在執行某一個操做的時候可能會由於停電、網絡中斷等緣由而出現故障,因此有可能更新了一個表中的行,但沒有更新相關表中的行。若是數據庫支持事務,則能夠將數據庫操做組成一個事務,以防止因這些事件而使數據庫出現不一致。

事務的ACID屬性以下。

l  原子性(Atomicity):事務的全部操做是原子工做單元;對於其數據修改,要麼全都執行,要麼全都不執行。原子性消除了系統處理操做子集的可能性。

l  一致性(Consistency):數據從一種正確狀態轉換到另外一種正確狀態。事務在完成時,必須使全部的數據都保持一致。在相關數據庫中,全部規則都必須應用於事務的修改,以保持全部數據的完整性。當事務結束時,全部的內部數據結構都必須是正確的。在存款取款的例子中,邏輯規則是,錢是不能憑空產生或銷燬的,對於每一個(收支)條目必須有一個相應的抵衡條目產生,以保證帳戶是平的。

l  隔離性(Isolation):由併發事務所做的修改必須與任何其餘併發事務所做的修改隔離。查看數據時數據所處的狀態,要麼是事務修改它以前的狀態,要麼是事務修改它以後的狀態。簡單的理解就是,防止多個併發更新彼此干擾。事務在操做數據時與其餘事務操做隔離。隔離性通常是經過加鎖的機制來實現的。

l  持久性(Durability):事務完成以後,它對於系統的影響是永久性的。已提交的更改即便在發生故障時也依然存在。

對於事務的開發,.NET平臺也爲咱們提供了幾種很是簡單方便的事務機制。不管是在功能上仍是性能上都提供了優秀的企業級事務支持。

.NET開發者可使用如下5種事務機制:

l  SQL和存儲過程級別的事務。

l  ADO.NET級別的事務。

l  ASP.NET頁面級別的事務。

l  企業級服務COM+事務。

l  System.Transactions 事務處理。

5種事務機制有着各自的優點和劣勢,分別表如今性能、代碼數量和部署設置等方面。開發人員能夠根據項目的實際狀況選擇相應的事務機制。下面就開始分別說明平常開發中5種事務的具體使用。

 

.NET開發中的事務處理大比拼 之 SQL和存儲過程級別事務

.NET開發中的事務處理大比拼 之 ADO.NET級別的事務

.NET開發中的事務處理大比拼 之 ASP.NET頁面級別的事務

.NET開發中的事務處理大比拼 之 企業級服務COM+事務

.NET開發中的事務處理大比拼 之 System.Transactions

 

      選自《亮劍.NET. .NET深刻體驗與實戰精要》 5.4 節。

 

c# partial 關鍵字的使用

說一個場景:EntityFramework能夠自動建立數據庫映射的實體類,該類不可修改(更新時會清空自定義部分),相似Winform下自動生成的.designer.cs文件。所以能夠經過partial標記來編寫自定義的擴展功能。

 

 

 

C#之數據類型學習

 

C#有如下幾種數據類型:

image

數據類型案例以及取值範圍:

界面:

image

選擇int時:

image

選中long時:

image

選中float時:

image

選中double時:

image

選中decimal時:

image

選中string時:

image

選中char時:

image

選中Bool時:

image

源代碼以下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SecondWpf
{
     /// <summary>
     /// MainWindow.xaml 的交互邏輯
     /// </summary>
     public partial class MainWindow : Window
     {
         public MainWindow()
         {
             InitializeComponent();
         }

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
         {
          
         }

        private void Button_Click(object sender, RoutedEventArgs e)
         {
             Close();//當Quit鍵被按下之後,退出系統
         }

        private void ListBoxItem_Selected(object sender, RoutedEventArgs e)
         {
             int variable,IntMax,IntMin;
             variable = 42;
             IntMax = (int)Math.Pow(2, 32)-1;
             IntMin = (int)Math.Pow(-2, 32);
             Value.Text = variable.ToString() ;
             Down.Text = IntMin.ToString();
             Uper.Text = IntMax.ToString();
         }

        private void List1_Selected(object sender, RoutedEventArgs e)
         {
             long LongMax, LongMin,variable;
             variable = 42L;
      
             LongMax = (long)Math.Pow(2, 63) - 1;
             LongMin = (long)Math.Pow(-2, 63);
             Value.Text = variable.ToString();
             Down.Text = LongMax.ToString();
             Uper.Text = LongMin.ToString();
         }

        private void List2_Selected(object sender, RoutedEventArgs e)
         {
             float variable;
             string FloatMax, FloatMin;
             variable = 0.42f;
             FloatMax = "(+-)1.5*10^45";
             FloatMin = "(+-)3.4 * 10 ^ 45";
             Value.Text = variable.ToString();
             Down.Text = FloatMax;
             Uper.Text = FloatMin;
         }

        private void List3_Selected(object sender, RoutedEventArgs e)
         {
             double variable;
             string DoubleMax;
             string DoubleMin;
             variable = 0.43;
             DoubleMax = "+-5.0*10^-324";
             DoubleMin = "+-1.7*10^308";
             Value.Text = variable.ToString();
             Down.Text = DoubleMax;
             Uper.Text = DoubleMin;

        }

        private void List4_Selected(object sender, RoutedEventArgs e)
         {
             decimal coin;
             string DecimalMax, DecimalMin;
             coin = 0.42M;
             DecimalMax ="+-1.0*10^-28";
             DecimalMin = "+-7.9*10^28"; 
             Value.Text = coin.ToString();
             Down.Text = DecimalMax.ToString();
             Uper.Text = DecimalMin.ToString();
         }

        private void List5_Selected(object sender, RoutedEventArgs e)
         {
             string vest;
             vest = "你好!";
             Value.Text = vest;
             Down.Text = "null";
             Uper.Text = "null";
         }

        private void List6_Selected(object sender, RoutedEventArgs e)
         {
             char grill;
             int CharMax, CharMin;
             grill = 'x';
             CharMax = (int)Math.Pow(2, 16) - 1;
             CharMin = 0;
             Value.Text = grill.ToString();
             Down.Text = CharMin.ToString();
             Uper.Text = CharMax.ToString();
         }

        private void List7_Selected(object sender, RoutedEventArgs e)
         {
             bool teeth;
             teeth = false;
             Value.Text = teeth.ToString();
             Down.Text ="Ture";
             Uper.Text = "Flase";
         }
     }
}

 

 

 

距離上一篇文章《基於EF Core的Code First模式的DotNetCore快速開發框架》已過去大半個年頭,時光荏苒,歲月如梭。。。比較尷尬的是,在這大半個年頭裏,除了平常帶娃溜娃作飯,偶爾接幾個私單外,我的開源項目幾乎沒啥動靜。那麼平常工做幹些什麼呢?確定是堅守Nfx啊。。。爲何呢?不作Nfx那是不可能的,畢竟要吃飯...講真,大山城做爲新進一線網紅大城市環境,dotneter們活得很是堅挺的,眼看又一波猛漲的房價和這危機年,仍是默默加完班後夜跑幾十千米,鍛鍊好身體,多作幾單深夜兼職,興許運氣來了能碰一個少奮鬥20年的捷徑...前提是得作好各類滴水不漏的安全措施以防止猝死暴斃...

 

至於多坑仍是坑多,早已傻傻分不清,坊間謠傳民間大神的【重慶求職防坑手冊】早已被噴的不能自已,甚至已經下架

契機

前不久,科技巨頭微軟粑粑發佈了dotnetcore 2.1,以其一向的尿性做風,應該能夠上車了。然而我還在堅守Nfx,畢竟公司成熟平臺成熟產品以及成熟人力結構,冒然大躍進是確定要承擔各類被扣帽子風險的。雖然明面上上車無望,私下勾搭仍是有戲。前些時日,接到道友們熱情誠摯的需求,添加對DB First的支持,懶人有懶福...

更新內容

Gayhub地址:https://github.com/VictorTzeng/Zxw.Framework.NetCore
 
具體更新內容,大大小小仍是有點多,這裏就不囉嗦正經的話,具體狀況具體代碼裏見。
  1. 添加EFCore直接返回DataTable功能
  2. DBFirst功能,目前僅支持SQL Server、MySQL、NpgSQL三種數據庫。根據已存在的數據表直接生成實體代碼,詳見CodeGenerator
  3. 添加單元測試項目,並完成對以上兩點新功能的測試
  4. 引入IOC容器Aspectcore.Injector,詳見AspectCoreContainer.cs

手拿來,手把手摸你

目前僅支持Sqlserver、MySQL、NpgSQL等三種數據庫,具體用法以下:

  1. 注入DbContextOption
  2. 複製代碼
    1             services.Configure<DbContextOption>(options =>
    2             {
    3                 options.ConnectionString =
    4                     "User ID=zengxw;Password=123456;Host=localhost;Port=5432;Database=ZxwPgDemo;Pooling=true;";
    5             });
    6             services.AddScoped<IDbContextCore, PostgreSQLDbContext>(); //注入EF上下文
    複製代碼

    注入CodeGenerateOption

  3. 複製代碼
    1             services.Configure<CodeGenerateOption>(options =>
    2             {
    3                 options.OutputPath = "F:\\Test\\PostgreSQL";
    4                 options.ModelsNamespace = "Zxw.Framework.Website.Models";
    5                 options.IRepositoriesNamespace = "Zxw.Framework.Website.IRepositories";
    6                 options.RepositoriesNamespace = "Zxw.Framework.Website.Repositories";
    7                 options.ControllersNamespace = "Zxw.Framework.Website.Controllers";
    8             });
    複製代碼

    調用GenerateAllCodesFromDatabase生成全部代碼

1 CodeGenerator.GenerateAllCodesFromDatabase(true);

 

總結與計劃

工做之餘,多陪家人多陪孩子,多讀書多看報,多鍛鍊身體,畢竟錢是掙不完的。。。若是各位道友有多的能夠全都扔過來,哈哈哈
 
 

 

基於EF Core的Code First模式的DotNetCore快速開發框架

 

前言

最近接了幾個小單子,由於是小單子,項目規模都比較小,業務相對來講,也比較簡單。因此在選擇架構的時候,考慮到效率方面的因素,就採起了asp.net+entity framework中的code first模式,從而能夠進行快速開發。幾個單子作完下來,順便總結整理一下,近些時候也一直在學習dotnetcore,索性將項目都升級了,因而便有了這一套「基於EF Core的Code First模式的DotNetCore快速開發框架」。至於code first模式的優劣,此文將再也不贅述。至於本文的目的,一是爲了總結和整理工做這幾年所學的一些知識,方便之後可以快速高效地接入項目中。再是分享出來,跟你們一塊兒探討學習,一塊兒進步。歡迎各路大佬指正和建議^_^

 

項目地址

GitHub:

dotnetcore版本:https://github.com/VictorTzeng/Zxw.Framework.NetCore

.net framework版本:https://github.com/VictorTzeng/Zxw.Framework.Nfx

 

碼雲:

dotnetcore版本:https://gitee.com/ceo_bitch/Zxw.Framework.NetCore

.net framework版本:https://gitee.com/ceo_bitch/Zxw.Framework.Nfx

 

項目架構

此項目主要分紅兩部分:Zxw.Framework.NetCore (核心類庫)和 NetCore.Sample (示例)兩部分。如圖所示:

Zxw.Framework.NetCore 項目說明:

  • Attributes —— 一些經常使用的屬性
  • CodeGenerator —— 代碼生成器,用於生成Repository和Service層的代碼
  • CodeTemplate —— Repository和Service層代碼模板
  • EfDbContext —— EF上下文
  • Extensions —— 一些經常使用的擴展方法
  • Filters —— 一些經常使用的攔截器
  • Helpers —— 一些經常使用的幫助類
  • IoC —— IoC容器封裝類,Autofac
  • IRepositories —— Repository接口類
  • IServices —— Service接口類
  • Middlewares —— 中間件
  • Models —— 實體接口類,IBaseModel<TKey>
  • Options —— 一些經常使用的配置類
  • Repositories —— Repository層的父類
  • Services —— Service層的父類

框架使用

如 NetCore.Sample 所示,按照此項目結構建立好:

  • Zxw.Framework.Website —— 網站
  • Zxw.Framework.Website.Controllers —— 控制器
  • Zxw.Framework.Website.IRepositories —— 倉儲接口
  • Zxw.Framework.Website.IServices —— Service接口
  • Zxw.Framework.Website.Models —— 實體
  • Zxw.Framework.Website.Repositories —— 倉儲
  • Zxw.Framework.Website.Services —— Services
  • Zxw.Framework.Website.ViewModels —— ViewModels

安裝nuget package:

Install-Package Zxw.Framework.NetCore -Version 1.0.1

須要注意如下幾點:

  1. 全部實體都需實現IBaseModel<TKey>接口(TKey是主鍵類型),若是須要在數據庫中生成對應的數據表
  2. 若是IRepositories、IServices、Repositories、Services這四個項目沒有單獨創建,調用代碼生成器生成的代碼將存在於調用項目的目錄下
  3. 利用代碼生成器生成的代碼文件須要手動添加到項目中

實體示例:

複製代碼
 1 using System.ComponentModel.DataAnnotations;
 2 using System.ComponentModel.DataAnnotations.Schema;
 3 using Zxw.Framework.NetCore.Models;
 4 
 5 namespace Zxw.Framework.Website.Models
 6 {
 7     public class TutorClassType:IBaseModel<int>
 8     {
 9         [Key]
10         [Column("TutorClassTypeId")]
11         public int Id { get; set; }
12 
13         [Required]
14         [StringLength(maximumLength:50)]
15         public string TutorClassTypeName { get; set; }
16         public bool Active { get; set; } = true;
17         [StringLength(maximumLength:200)]
18         public string Remark { get; set; }
19         public int TutorClassCount { get; set; }
20     }
21 }
複製代碼

在Startup.cs文件中使用:

複製代碼
  1 using System;
  2 using System.Text;
  3 using log4net;
  4 using log4net.Repository;
  5 using Microsoft.AspNetCore.Builder;
  6 using Microsoft.AspNetCore.Hosting;
  7 using Microsoft.Extensions.Caching.Distributed;
  8 using Microsoft.Extensions.Caching.Memory;
  9 using Microsoft.Extensions.Configuration;
 10 using Microsoft.Extensions.DependencyInjection;
 11 using Zxw.Framework.NetCore.EfDbContext;
 12 using Zxw.Framework.NetCore.Filters;
 13 using Zxw.Framework.NetCore.Helpers;
 14 using Zxw.Framework.NetCore.IoC;
 15 using Zxw.Framework.NetCore.Options;
 16 
 17 namespace Zxw.Framework.Website
 18 {
 19     public class Startup
 20     {
 21         public static ILoggerRepository repository { get; set; }
 22         public Startup(IConfiguration configuration)
 23         {
 24             Configuration = configuration;
 25             //初始化log4net
 26             repository = LogManager.CreateRepository("NETCoreRepository");
 27             Log4NetHelper.SetConfig(repository, "log4net.config");
 28         }
 29 
 30         public IConfiguration Configuration { get; }
 31 
 32         // This method gets called by the runtime. Use this method to add services to the container.
 33         public IServiceProvider ConfigureServices(IServiceCollection services)
 34         {
 35             services.AddMvc(option=>
 36             {
 37                 option.Filters.Add(new GlobalExceptionFilter());
 38             });
 39             services.AddMemoryCache();//啓用MemoryCache
 40             services.AddDistributedRedisCache(option =>
 41             {
 42                 option.Configuration = "localhost";//redis鏈接字符串
 43                 option.InstanceName = "";//Redis實例名稱
 44             });//啓用Redis
 45             services.Configure<MemoryCacheEntryOptions>(
 46                     options => options.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)) //設置MemoryCache緩存有效時間爲5分鐘。
 47                 .Configure<DistributedCacheEntryOptions>(option =>
 48                     option.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5));//設置Redis緩存有效時間爲5分鐘。
 49             return InitIoC(services);
 50         }
 51 
 52         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
 53         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 54         {
 55             Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
 56             if (env.IsDevelopment())
 57             {
 58                 app.UseDeveloperExceptionPage();
 59                 app.UseBrowserLink();
 60             }
 61             else
 62             {
 63                 app.UseExceptionHandler("/Home/Error");
 64             }
 65 
 66             app.UseStaticFiles();
 67             
 68             app.UseMvc(routes =>
 69             {
 70                 routes.MapRoute(
 71                     name: "default",
 72                     template: "{controller=Home}/{action=Index}/{id?}");
 73             });
 74         }
 75         /// <summary>
 76         /// IoC初始化
 77         /// </summary>
 78         /// <param name="services"></param>
 79         /// <returns></returns>
 80         private IServiceProvider InitIoC(IServiceCollection services)
 81         {
 82             var connectionString = Configuration.GetConnectionString("MsSqlServer");
 83             var dbContextOption = new DbContextOption
 84             {
 85                 ConnectionString = connectionString,
 86                 ModelAssemblyName = "Zxw.Framework.Website.Models",
 87                 DbType = DbType.MSSQLSERVER
 88             };
 89             var codeGenerateOption = new CodeGenerateOption
 90             {
 91                 ModelsNamespace = "Zxw.Framework.Website.Models",
 92                 IRepositoriesNamespace = "Zxw.Framework.Website.IRepositories",
 93                 RepositoriesNamespace = "Zxw.Framework.Website.Repositories",
 94                 IServicsNamespace = "Zxw.Framework.Website.IServices",
 95                 ServicesNamespace = "Zxw.Framework.Website.Services"
 96             };
 97             IoCContainer.Register(Configuration);//註冊配置
 98             IoCContainer.Register(dbContextOption);//註冊數據庫配置信息
 99             IoCContainer.Register(codeGenerateOption);//註冊代碼生成器相關配置信息
100             IoCContainer.Register(typeof(DefaultDbContext));//註冊EF上下文
101             IoCContainer.Register("Zxw.Framework.Website.Repositories", "Zxw.Framework.Website.IRepositories");//註冊倉儲
102             IoCContainer.Register("Zxw.Framework.Website.Services", "Zxw.Framework.Website.IServices");//註冊service
103             return IoCContainer.Build(services);
104         }
105     }
106 }
複製代碼

使用代碼生成器:

複製代碼
 1 using System;
 2 using System.Diagnostics;
 3 using Microsoft.AspNetCore.Mvc;
 4 using Zxw.Framework.NetCore.CodeGenerator;
 5 using Zxw.Framework.NetCore.Helpers;
 6 using Zxw.Framework.Website.IServices;
 7 using Zxw.Framework.Website.ViewModels;
 8 using Zxw.Framework.Website.Models;
 9 
10 namespace Zxw.Framework.Website.Controllers
11 {
12     public class HomeController : Controller
13     {
14         private ITutorClassTypeService iTutorClassTypeService;
15 
16         public HomeController(ITutorClassTypeService tutorClassTypeService)
17         {
18             if(tutorClassTypeService==null)
19                 throw new ArgumentNullException(nameof(tutorClassTypeService));
20             iTutorClassTypeService = tutorClassTypeService;
21         }
22         public IActionResult Index()
23         {
24             CodeGenerator.Generate();//生成全部實體類對應的Repository和Service層代碼文件
25             CodeGenerator.GenerateSingle<TutorClassType, int>();//生成單個實體類對應的Repository和Service層代碼文件
26 
27             return View();
28         }
29 
30         public IActionResult About()
31         {
32             ViewData["Message"] = "Your application description page.";
33 
34             return View();
35         }
36 
37         public IActionResult Contact()
38         {
39             ViewData["Message"] = "Your contact page.";
40 
41             return View();
42         }
43 
44         public IActionResult Error()
45         {
46             return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
47         }
48 
49         protected override void Dispose(bool disposing)
50         {
51             if (disposing)
52             {
53                 iTutorClassTypeService.Dispose();
54             }
55             base.Dispose(disposing);
56         }
57     }
58 }
複製代碼

 

總結

寫博客真的很費力,但願本身可以堅持下去。

最後,歡迎各路大佬建議和拍磚~~

 

 

【懶人有道】在asp.net core中實現程序集註入

 

 

前言

在asp.net core中,我巨硬引入了DI容器,咱們能夠在不使用第三方插件的狀況下輕鬆實現依賴注入。以下代碼:
複製代碼
 1         // This method gets called by the runtime. Use this method to add services to the container.
 2         public void ConfigureServices(IServiceCollection services)
 3         {
 4             //services.RegisterAssembly("IServices");
 5             services.AddSingleton<IUserService, UserService>();
 6             // Add framework services.
 7             services.AddMvc();
 8             services.AddMvcCore()
 9                 .AddApiExplorer();
10             services.AddSwaggerGen(options =>
11             {
12                 options.SwaggerDoc("v1", new Info()
13                 {
14                     Title = "Swagger測試",
15                     Version = "v1",
16                     Description = "Swagger測試RESTful API ",
17                     TermsOfService = "None",
18                     Contact = new Contact
19                     {
20                         Name = "來來吹牛逼",
21                         Email = "xxoo123@outlook.com"
22                     },
23                 });
24                 //設置xml註釋文檔,注意名稱必定要與項目名稱相同
25                 var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "WebApi.xml");
26                 options.IncludeXmlComments(filePath);
27             });
28         }
複製代碼

 

可是,隨着公司業務的擴大,系統項目的功能模塊急劇擴張,新增了不下百個或者千個Repository和Service(有點誇張了...),這時候如此單純滴注入就有點操蛋了。

打懶主意

我可不能夠經過反射技術來實現對程序集的注入呢??

試試就試試

首先,我私自先制定一些類名的約束。規則嘛,反正是本身定。好比:
  • UserService --> IUserService
  • UserRepository --> IUserRepository
  • ......
  • ClassName --> IClassName
好了,咱們下面開始編碼:
複製代碼
 1     /// <summary>
 2     /// IServiceCollection擴展
 3     /// </summary>
 4     public static class ServiceExtension
 5     {
 6         /// <summary>
 7         /// 用DI批量注入接口程序集中對應的實現類。
 8         /// <para>
 9         /// 須要注意的是,這裏有以下約定:
10         /// IUserService --> UserService, IUserRepository --> UserRepository.
11         /// </para>
12         /// </summary>
13         /// <param name="service"></param>
14         /// <param name="interfaceAssemblyName">接口程序集的名稱(不包含文件擴展名)</param>
15         /// <returns></returns>
16         public static IServiceCollection RegisterAssembly(this IServiceCollection service, string interfaceAssemblyName)
17         {
18             if (service == null)
19                 throw new ArgumentNullException(nameof(service));
20             if (string.IsNullOrEmpty(interfaceAssemblyName))
21                 throw new ArgumentNullException(nameof(interfaceAssemblyName));
22 
23             var assembly = RuntimeHelper.GetAssembly(interfaceAssemblyName);
24             if (assembly == null)
25             {
26                 throw new DllNotFoundException($"the dll \"{interfaceAssemblyName}\" not be found");
27             }
28 
29             //過濾掉非接口及泛型接口
30             var types = assembly.GetTypes().Where(t => t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType);
31 
32             foreach (var type in types)
33             {
34                 var implementTypeName = type.Name.Substring(1);
35                 var implementType = RuntimeHelper.GetImplementType(implementTypeName, type);
36                 if (implementType != null)
37                     service.AddSingleton(type, implementType);
38             }
39             return service;
40         }
41 
42         /// <summary>
43         /// 用DI批量注入接口程序集中對應的實現類。
44         /// </summary>
45         /// <param name="service"></param>
46         /// <param name="interfaceAssemblyName">接口程序集的名稱(不包含文件擴展名)</param>
47         /// <param name="implementAssemblyName">實現程序集的名稱(不包含文件擴展名)</param>
48         /// <returns></returns>
49         public static IServiceCollection RegisterAssembly(this IServiceCollection service, string interfaceAssemblyName, string implementAssemblyName)
50         {
51             if (service == null)
52                 throw new ArgumentNullException(nameof(service));
53             if(string.IsNullOrEmpty(interfaceAssemblyName))
54                 throw new ArgumentNullException(nameof(interfaceAssemblyName));
55             if (string.IsNullOrEmpty(implementAssemblyName))
56                 throw new ArgumentNullException(nameof(implementAssemblyName));
57 
58             var interfaceAssembly = RuntimeHelper.GetAssembly(interfaceAssemblyName);
59             if (interfaceAssembly == null)
60             {
61                 throw new DllNotFoundException($"the dll \"{interfaceAssemblyName}\" not be found");
62             }
63 
64             var implementAssembly = RuntimeHelper.GetAssembly(implementAssemblyName);
65             if (implementAssembly == null)
66             {
67                 throw new DllNotFoundException($"the dll \"{implementAssemblyName}\" not be found");
68             }
69 
70             //過濾掉非接口及泛型接口
71             var types = interfaceAssembly.GetTypes().Where(t => t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType);
72 
73             foreach (var type in types)
74             {
75                 //過濾掉抽象類、泛型類以及非class
76                 var implementType = implementAssembly.DefinedTypes
77                     .FirstOrDefault(t => t.IsClass && !t.IsAbstract && !t.IsGenericType &&
78                                          t.GetInterfaces().Any(b => b.Name == type.Name));
79                 if (implementType != null)
80                 {
81                     service.AddSingleton(type, implementType.AsType());
82                 }
83             }
84 
85             return service;
86         }
87     }
複製代碼

附上RuntimeHelper.cs的代碼:

複製代碼
 1     public class RuntimeHelper
 2     {
 3         /// <summary>
 4         /// 獲取項目程序集,排除全部的系統程序集(Microsoft.***、System.***等)、Nuget下載包
 5         /// </summary>
 6         /// <returns></returns>
 7         public static IList<Assembly> GetAllAssemblies()
 8         {
 9             var list = new List<Assembly>();
10             var deps = DependencyContext.Default;
11             var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");//排除全部的系統程序集、Nuget下載包
12             foreach (var lib in libs)
13             {
14                 try
15                 {
16                     var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
17                     list.Add(assembly);
18                 }
19                 catch (Exception)
20                 {
21                     // ignored
22                 }
23             }
24             return list;
25         }
26 
27         public static Assembly GetAssembly(string assemblyName)
28         {
29             return GetAllAssemblies().FirstOrDefault(assembly => assembly.FullName.Contains(assemblyName));
30         }
31 
32         public static IList<Type> GetAllTypes()
33         {
34             var list = new List<Type>();
35             foreach (var assembly in GetAllAssemblies())
36             {
37                 var typeInfos = assembly.DefinedTypes;
38                 foreach (var typeInfo in typeInfos)
39                 {
40                     list.Add(typeInfo.AsType());
41                 }
42             }
43             return list;
44         }
45 
46         public static IList<Type> GetTypesByAssembly(string assemblyName)
47         {
48             var list = new List<Type>();
49             var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
50             var typeInfos = assembly.DefinedTypes;
51             foreach (var typeInfo in typeInfos)
52             {
53                 list.Add(typeInfo.AsType());
54             }
55             return list;
56         }
57 
58         public static Type GetImplementType(string typeName, Type baseInterfaceType)
59         {
60             return GetAllTypes().FirstOrDefault(t =>
61             {
62                 if (t.Name == typeName &&
63                     t.GetTypeInfo().GetInterfaces().Any(b => b.Name == baseInterfaceType.Name))
64                 {
65                     var typeInfo = t.GetTypeInfo();
66                     return typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.IsGenericType;
67                 }
68                 return false;
69             });
70         }
71     }
複製代碼

好了,到此就基本完成了,記得在Startup.cs加上:

複製代碼
1 // This method gets called by the runtime. Use this method to add services to the container.
2         public IServiceProvider ConfigureServices(IServiceCollection services)
3         {
4             services.RegisterAssembly("IServices");
5          
6             // Add framework services.
7             services.AddMvc();
8         }
複製代碼
相關文章
相關標籤/搜索