C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架...

2020年05月14日 阅读数:52
这篇文章主要向大家介绍C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架...,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

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         }
复制代码

 

 

转载于:https://www.cnblogs.com/cjm123/p/9278011.html