关闭鼠标悬停时自动出现快速文档浮层的方法,历险之旅
分类:多线程

就是这个烦人的图层,像打不跑的苍蝇

文章背景:对于.NET Core大家应该并不陌生, 从它被 宣布 到现在已经有1-2年的时间了,其比较重要的一个版本1.0 RC2 也即将发布。.Net Core从一个一个的测试版到现在的RC2,经历了很多个大大小小的变化。特别是在RC1到RC2的更新之中,.NET Core命令行工具(dotnet cli)从 dnx 变为 dotnet,并且废除了 DNVM 和 DNU,使得 .NET Core 的开发变得更为简单,其相关工具链也基本成型。虽然网上关于.NET Core的示例项目不在少数,而且微软官方也提供了不少示例项目,但大多针对的是.NET Core的不同版本,因此很多示例项目并不是能很容易的运行起来。所以我决定写一篇针对RC2这个版本的.NET Core入门文章并提供一些能直接运行的示例项目。

1、.NET是什么?         .Net全称.NET Framework是一个开发和运行环境,
        该战略是微软的一项全新创意,
        它将使得“互联网行业进入一个更先进的阶段”,
        .NET不是一种编程语言. 简单说就是一组类库框架,
        .NET开发支持C#、VB.NET、J#、Jsript和Managed C++等。
        C#是.NET Framework框架支持的一种主力开发语言,
        可用于开发ASP.NET网站, Windows 程序,控制台程序,甚至于手机软件,
2、ASP.NET、.NET和C#的关系是怎样的?
        .NET 分成两个方面:
        (1)WinForm
        (2)WebForm
        ASP.NET就是属于WebForm,也就是平时说的B/S模式的开发。
        而WinForm就是属于C/S模式。
        .NET有很多种语言组成,比如C#、 VB.NET、J#、Jsript、Managed C++
        但是都是运行在.NET FrameWork Run Time底下的。
        Asp.NET 可以用C#或VB.NET来开发。
        编译后形成CLR,通过服务器的IIS+.NET FrameWork再次编译来运行。
        C#是开发语言.
        总之,ASP.NET是.NET Framework环境下的动态网页编程技术,
        .NET Framework是.NET的基础框架,
        Visual Studio.NET是用于开发软件的一个集成环境(IDE)。
3、.NET开发是用什么语言?
        .NET声称支持市面上20多种语言,但目前
        只有微软官方发布的C#,VB.NET,J#, Jsript和Managed C++
4、为什么大部分用C#语言开发.NET?         C#是Microsoft公司设计的一种编程语言,
        C#(读做‘Csharp')。它基于C/C++,是面向对象的.
        没有指针,有垃圾回收机制,会自动释放内存空间。
        学习C#并不必须有C语言的基础,不过,如果你学过C语言,
        那会事半功倍的,因为他们之间有很多语法是一样的。
        C#支持的基本类型和C++很相似,包括int, long,
        float, double, char, string, arrays, structs和 classes等。
5、ASP.NET环境的安装
        (1)、其实现在一般的电脑都可以安装,至于操作系统目前
        .NET支持的平台有Windows,至于Linux和Unix的支持正在开发中.
        Microsoft Windows 2000windows xp sp3windows 2003的操作系统
        (2)、运行环境下载,因为是向下兼容,所以可以下载最新的Framework框架
        .NET Framwork 2.0官方下载地址:
        .NET Framework 3.5下载地址:

        .NET Framework 4.0下载地址:

        (3)、安装过程
        首选安装MDAC,再安装SDK,SDK的安装时间比较长要耐心等待。
        (4)、试运行
        安装完成后,试着运行一个简单的ASP.NET编写的小程序,以便确定安装是否成功。
6、Bin文件夹下的DLL可以做什么?
        (1)它是自动生成的,不用自己添加。
        (2)作用:bin文件夹中包含项目中所用到的所有引用的类库,支持服务器等内容
        DLL的全称是Dynamic Link Library, 中文叫做“动态链接文件”。
7、.NET主要的优点有哪些?
        .NET的主要优点有跨语言,跨平台,安全,以及对开放互联网标准和协议的支持.
        .NET支持多种语言的互操作,即在一种语言下开发的组件,
        可在另一组件下通过面向对象的继承而得以重用.
        .NET通过将各语言先编译成中间语言(IL),
        然后再执行时用即时(Just In Time)编译器将之编译成本地平台代码来实现异构平台下对象的互操作,
        .NET通过公共语言运行库CLR(Common Language Runtime)来实现资源对象,类型的安全.
        .NET通过对HTTP,XML等Internet标准的支持提供在异构网络环境下获取远程服务,
        连接远程设备,交互远程应用的编程界面
8、ASP.NET和ASP的区别?
        ASP.NET和ASP的最大区别在于编程思维的转换以及功能的增强。
        ASP使用VB/JS这样的弱类型、面向结构的脚本语言混合html来编程,
        而非面向对象,这就明显产生以下几个问题:
        1、代码逻辑混乱,难于管理。
        2、代码的可重用性差:由于是面向结构的编程方式,并且混合html,
          所以可能页面原型修改一点,整个程序都需要修改,代码重用性差。
        3、弱类型造成潜在的出错可能。
        以上是ASP语言本身的弱点,在功能方面ASP同样存在问题:
        第一是功能太弱,一些底层操作只能通过组件来完成
        第二缺乏完善的纠错/调试功能
        ASP.NET理论上可以使用任何编程语言包括C#,VB.NET、JS、、J#、Managed C++等等,
        最合适的编程语言还是MS为.NET Frmaework专门推出的C#
        优点如下:
        (1)是面向对象的编程语言,简单易学。
        (2)具有面向对象编程语言的一切特性,比如封装性、继承性、多态性等等,
        封装性使得代码逻辑清晰,并且应用到ASP.NET上就可以使业务逻辑和Html页面分离;
        继承性和多态性使得代码的可重用性大大提高
        (3)C#还提供了完善的调试/纠错体系。
9、做项目时数据库类型的选择?
        当前流行的数据库有:Sql server,MySql,Oracle,DB2。
        VS项目中大多是选择以下四种:
        Sql2000简单实用,功能完全够学习时使用,可通过命令行快速打开;
        Sql2005功能全面,但安装麻烦,体积大,刚打开数据库的时候比较慢,启动之后就快了许多;
        Sql2008新出的数据库,功能肯定比前两者强大,建议使用Sql2005的用户升级到Sql2008;
        ACCESS体积小、部署方便(不用启动服务等)使用方便简单.
10、ASP.NET中经常使用的控件有哪些?
        Label控件用来显示文本的控件。Label控件不能接收鼠标或是键盘输入。
        TextBox控件来显示和更新任务数据,用户输入内容。
        Button按钮控件当用户单击或者点击一个按钮时,即会触发Click事件
        ListBox和ComboBox控件外观不同,但功能极为相似,允许用户进行选择,不允许输入文本。
11、.net开发工具都有哪些?
        现在主流是Visual Studio 2005/2008,但是不少小企业仍然固执使用vs2003,
        不过最近vs2010也上市了。
        VS提供了下列几个版本:标准版、专业版、Tools for Office 和 Team System 版。
        还有C# builder只应用于大型企业开发,
        支持一些微软的vs.net都不支持的企业级功能。
        还有一款免费的开发工具web matrix,这款自动感知能力弱到几乎没有,
        适合开发页面和代码不分开的那种页面,可以提高独立写代码的水平。
        不过他带有.net类库浏览器,以及一个数据库开发的控件,也算是有些特点。
        入门初学者VS.NET会很容易上手,
        当然,还有就是高手只用记事本咯!
12、为什么.NET程序第一次运行比较慢?        aspx页面在运行时,第一次访问时要进行编译。
        当你再次运行时,由于缓存机制,速度就会正常了。
13、C#的命名规范
        主要有Pascal和Camel两种
        Pascal:单词的首字母大写,如ProductType;
        Camel:首个单词的首字母小写,其余单词的首字母大写,如productType)
          以下是一些常用的C#成员及其推荐命名方法:
          类class:Pascal
          枚举类型enum:Pascal记住,是以Pascal命名,切勿包含Enum
          委托delegate:Pascal以Pascal命名,不以任何特殊字符串区别于类名、函数名
          接口interface:Pascal注:总是以"I"前缀开始,后接Pascal命名
          方法function: Pascal               
          命名空间namespace: Pascal比如:usingExcelQuicker.Framework
          属性:Pascal
          参数:Camel 首字母小写               
          常量const: Camel 字母全部大写
          局部变量:Camel 声明变量是以str开头
          数据成员:Camel 以m开头+Pascal命名规则,如mProductType(m意味member)
14、如何判断一个程序是否开源或者是有源文件?
        都有对应的.CS文或VB文件
        有项目文件和解决方案文件
        BIN文件下所有的dll文件或是引用的组件有对应的源码

转载:

QQ截图20190619164332.png (上传于2019-06-22 20:40:20)
图片 1

下载安装 .NET Core SDK

从 dotnet cli github项目主页找到最新版的.Net Core SDK下载:

例如 Mac OS X的最新版的.NET Core SDK的下载地址为:

安装前请确认当前系统是否已经安装了老版本的.NET Core, 如果已经安装,请先卸载。

如在Mac OS X上已安装的话,请运行如下命令删除:

sudo rm -rf /usr/local/share/dotnet

在Mac OS X上安装之前请先确保 openssl 已经被安装了:

brew install openssl

本书是一本讲解.NET技术的书籍,目标读者群也是在.NET框架(.NET Framework)下进行开发的程序员,因此我们无法回避的问题就是:什么是.NET框架?它包含了哪些内容?为开发程序提供了哪些支持?很多朋友对这类个问题的第一反应可能是.NET框架所提供的庞大类库及编写代码所采用的C#语言,实际上远不止这些。

我在上篇博客狠狠的吐槽了这个设计 https://blog.bccn.net/静夜思/66713 ,不解决掉这个问题终日寝食难安。

开发工具 Visual Studio Code 及其 C# 插件安装

如不准备使用VSCode进行开发的话,请忽略此部分。我不确定最新版本的 Visual Studio 2015 Update 2 是否对.NET Core 1.0 RC2有很好的支持。

  1. 从官方网站下载安装 VSCode

  2. 安装VSCode C#插件

    由于支持 RC2 的 C# 插件 v1.0 还未正式发布到 VS Code extension 仓库里, 因此你只能手动从github下载并安装:

    Mac OS X 下通过 VSCode 打开下载下来的文件即可。

    等到 VS Code C# 插件 v1.0 版本正式发布了,你就可以通过VSCode的命令窗口来安装 C# 支持了。详细操作如下:

    运行VSCode, 然后使用快捷键 ⌘ + P 启动快速打开命令窗口,然后输入如下命令安装C#扩展。最新版的csharp扩展已支持 RC2 的.NET程序的调试。

    ext install csharp
    

要描述.NET框架,自然会遇到与其相关的一系列专业的技术术语和缩写,相信大家已经见到过许多了,比如:CLI、CIL、CTS、CLS、CLR、JIT、BCL、FCL、Module、Assembly 等,足以让很多人一头雾水、望而却步。笔者不会像字典一样按首字母排序对术语进行逐一解释,因为这样还是难以理解。我们还是从大家最熟悉的东西开始吧!

苍天有眼,今天让我搜到一个10年前的帖子 10年前就有人受这个困扰(然而官僚化的微软始终听不到用户的声音),并且开发了一个扩展,当然这个扩展现在已经不能用了。好在给了我一个启发。

使用.NET CLI (dotnet) 创建,编译和运行项目

  1. 创建项目

首先在控制台/Terminal下进入你要创建项目的目录,然后运行如下命令:

    dotnet new

dotnet cli 创建新项目的时候支持项目类型参数-t,但当前只支持Console参数。:(

运行之后会生成两个文件

    project.json    -   类似于.NET Framework里的项目文件
    Program.cs      -   程序启动入口

使用restore命令下载依赖

    dotnet restore

如出现网络错误导致restore失败的情况请重试几次,貌似这种情况比较少。

如发现类似下面的Warning也请不要惊慌,这是由于CLI的版本号与下载下来的.NET Core类库的版本号不一致导致的,这种情况不会影响编译和运行。

    warn : Dependency specified was Microsoft.NETCore.App (>= 1.0.0-rc2-3002464) but ended up with Microsoft.NETCore.App 1.0.0-rc2-3002468.
  1. 编译项目

在控制台或Terminal打开项目所在目录,运行如下命令编译:

    dotnet build

如出现如下类似编译错误:

   error NU1002: The dependency Microsoft.CodeAnalysis.Common 1.2.0-beta1-20160202-02 does not support framework .NETCoreApp,Version=v1.0
   error NU1002: The dependency Microsoft.CodeAnalysis.CSharp 1.2.0-beta1-20160202-02 does not support framework .NETCoreApp,Version=v1.0

出现这个问题的可能原因是NuGet上通过版本号匹配到的依赖包并不能使用,你需要做如下操作之后再重新restore一下。

a. 在项目根目录新增文件 NuGet.config, 并写入以下内容:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <packageSources>
            <!--To inherit the global NuGet package sources remove the <clear/>line below -->
            <clear/>
            <add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json"/>
            <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json"/>
        </packageSources>
    </configuration>

b. 打开 project.json 文件将 dependencies 节点中的 Microsoft.NETCore.App 的版本好更改为 1.0.0-rc2-*:

    "dependencies": {
        "Microsoft.NETCore.App": {
            "type": "platform",
            "version": "1.0.0-rc2-*"
        }
    }

c. 然后再重新运行 dotnet restore 之后编译

  1. 运行项目

    在控制台或Terminal打开项目所在目录,运行如下命令运行:

    dotnet run
    

    如遇如下错误,

    Expected to load libhostpolicy.dylib from [/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.0-rc2-3002468]
    This may be because the targeted framework ["Microsoft.NETCore.App": "1.0.0-rc2-3002468"] was not found.
    

    也不要慌张,到目录 bin/Debug/netcoreapp1.0中 找到文件 *.runtimeconfig.json, 将其中 runtime 版本号修改为与本机 CLI 版本号一致即可。

    {
        "runtimeOptions": {
            "framework": {
                "name": "Microsoft.NETCore.App",
                "version": "1.0.0-rc2-3002485"
            }
        }
    }
    

    如本机 dotnet --version 命令返回值为 “1.0.0-rc2-002485”,则应runtime config中的版本号应替换为“1.0.0-rc2-3002485”。

    然后再尝试运行 dotnet run

  2. 调试项目 (Visual Studio Code)

    使用 VSCode 打开项目所在文件夹之后,VSCode 会问你是否添加启用项目调试相关的文件,你选OK之后目录下会新增文件夹“.vscode”,其中会包含两个文件:

    launch.json
    tasks.json
    

    当你发现无法调试失败的时候,你可以到 launch.json 文件,检查启动所指向的文件是否正确:

    {
        "name": ".NET Core Launch (console)",
        ...
        "program": "${workspaceRoot}/bin/Debug/netcoreapp1.0/netcore.dll",
        ...
    }
    

6.1 引子

设想一下:编写下面这样一个最简单的显示“Hello, World!”的控制台程序,并将该程序运行起来需要哪几个步骤呢?

using System;
 
class Program {
    static void Main(string[] args) {
        string text = "hello, world!";
        Console.WriteLine(text);
    }
}

这些步骤包括:打开Visual Studio,创建一个C#控制台应用程序项目(在这里将它命名为ConsoleApp),编写代码,编译程序然后运行。虽然这样的程序谁都会写,但是再多进行一下思考就会发现,尽管是一个很小的程序,但已经引入了.NET框架的几个重要方面。

如果创建一个VB.NET类型的项目,实现和上面C#项目完全一样的功能,那么编译后生成的文件有什么区别?

编写控制台应用程序,将字符输出到屏幕,需要调用Console.WriteLine()方法。这个Console类型从何而来呢?

生成的文件在系统中是如何运行起来的?其机制和使用传统VC++生成的可执行文件是否相同?

其实,上面每一个问题的答案都包含.NET框架所提供的支持,这里将它分为三个部分:

  • 对于编译后生成的文件格式和内容,.NET中存在着诸多规范。符合这些规范的程序语言,也叫做面向.NET的语言。编译后生成的文件都可以在.NET运行时下执行,这就是大家所熟知的.NET多语言支持。
  • 在开发阶段,.NET提供了一个庞大的类库,支持开发者快速开发各种应用程序,也支持程序语言设计者开发其语言编译器。
  • 在程序执行阶段,.NET提供了一个程序运行时的环境,这个运行时环境帮助我们管理内存、实时编译程序、进行安全检查、执行垃圾回收等。

接下来就针对上述内容开始为大家详细讲述。

于是我开始搜vs的扩展,联机搜“tooltips”关键字的时候搜到一个叫“Tame Visual Studio Editor Tooltips”的扩展,看上去像是关于编辑器Tooltips的,仔细看了一下介绍,果然是解决这个问题的。点击download安装即可。扩展详细介绍:

使用 .NET Core 进行 ASP.NET MVC 开发

虽然 dotnet cli 并没有提供直接创建 web/mvc项目的选项,但是我们还是可以手动来创建 mvc 项目的。

  1. 首先是更新 project.json 来支持 mvc:

    {
        "version": "1.0.0-*",
        "content": [
            "wwwroot",
            "Views"
        ],
        "compilationOptions": {
            "preserveCompilationContext": true,
            "emitEntryPoint": true,
            "debugType": "portable"
        },
        "dependencies": {
            "Microsoft.AspNetCore.Diagnostics": "1.0.0-*",
            "Microsoft.AspNetCore.Mvc": "1.0.0-*",
            "Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0-*",
            "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-*",
            "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*",
            "Microsoft.AspNetCore.StaticFiles": "1.0.0-*",
            "Microsoft.Extensions.Logging.Console": "1.0.0-*",
            "Microsoft.NETCore.App": {
                "type": "platform",
                "version": "1.0.0-rc2-*"
            }
        },
        "frameworks": {
            "netcoreapp1.0": {
            "imports": [
                "portable-net45+wp80+win8+wpa81+dnxcore50"
            ]
            }
        },
        "tools": {
            "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
            "version": "1.0.0-*",
            "imports": "portable-net45+wp80+win8+wpa81+dnxcore50"
            }
        },
        "scripts": {
            "postpublish": "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%"
        }
    }
    
  2. 在NuGet.config 文件中增加 ASP.NET 的包的下载地址,如此文件不存在请先添加:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <packageSources>
            <!--To inherit the global NuGet package sources remove the <clear/> line below -->
            <clear />
            <add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
            <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
            <add key="AspNetCI" value="https://www.myget.org/F/aspnetcirelease/api/v3/index.json" />
        </packageSources>
    </configuration>
    
  3. 增加 Startup.cs 文件 然后在 Program.cs 增加启动代码:

    Startup.cs

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    
    namespace HelloMvc
    {
        public class Startup
        {
            public void ConfigureServices(IServiceCollection services)
            {
                // 注册MVC相关服务到ASP.NET Core的反转控制器
                services.AddMvc();
            }
    
            public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
            {
                loggerFactory.AddConsole(LogLevel.Debug);
    
                //启用静态文件支持
                app.UseStaticFiles();
    
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                // 启用 Mvc 并定义默认的路由
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    }
    

    Program.cs

    using System;
    using System.IO;
    using Microsoft.AspNetCore.Hosting;
    
    namespace HelloMvc
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var host = new WebHostBuilder()
                            .UseKestrel()
                            .UseContentRoot(Directory.GetCurrentDirectory())
                            .UseDefaultHostingConfiguration(args)
                            .UseIISIntegration()
                            .UseStartup<Startup>()
                            .Build();
    
                host.Run();
            }
        }
    }
    
  4. MVC 其它

    ASP.NET Core中 MVC 具体的开发方法,请参考官方文档 来学习使用,我在这里就不再累述了。
    完整示例可参考我在github上的示例项目:

    MVC项目也可通过 dotnet run 命令运行,还可以使用VSCode进行调试。

6.2 CIL——公共中间语言

首先要了解的就是C#程序源码在编译之后会得到什么样的一个文件。大家知道,过去使用VC++生成的可执行文件,经过预编译、编译、汇编、链接几个步骤后,最终生成的可执行文件中就已经包含了处理器的本地代码(Native Code),支持它运行的只是操作系统和本地的机器指令集。那么采用C#编译器生成的文件又是什么呢?现在需要引入程序集这个概念:在.NET框架下,类似C#这样的高级语言经过编译后生成的结果文件被称做程序集,其后缀名是.dll(类库)或.exe(可执行程序)。在引入这个概念之前,前面(上一节)提到程序集时,都是用“文件”这个词来描述的。

程序集的定义只是给编译后生成的文件一个稍微正式一点的名称,对于解释“它是由什么构成的”这个问题并没有太大的帮助。为了进一步了解程序集,我们再来做一个试验,使用VB.NET创建一个控制台应用程序项目(ConsoleAppVB),并生成一个程序集,代码功能和上面用C#创建的项目是一样的的。

Module Program
Sub Main()
Dim text AsString = "hello, world !"
        Console.WriteLine(text)
EndSub
EndModule

现在,需要一个工具来查看这个程序集的内容,并且与C#项目生成的程序集进行对比。还好,微软已经提供了一个利器——IL DASM(IL Disassembler,IL反汇编程序)来帮助开发者查看程序集的信息。如果安装了Visual Studio,IL DASM将会随同Visual Studio一起安装。依次选择开始菜单→ Microsoft Visual Studio 2010 → Microsoft Windows SDK Tools →IL 反汇编程序(IL DASM)可以启动IL DASM。

打开IL DASM后选择VB.NET项目生成的ConsoleAppVB.exe,可以看到如图6-1所示的界面。

图片 2

图6-1 IL DASM 运行界面

这部分内容很多,会在下一章“程序集”中进行专门讲述,,这里暂且略过。展开图6-1中的ConsoleAppVB.Program类型,在Main()方法上双击,会弹出另外一个窗口,显示图6-2中的代码,看上去有点像汇编语言。在这里可以看到熟悉的string text变量声明及“hello, world !”。

图片 3

图6-2 方法体的CIL语言描述(VB.NET)

接下来再打开C#项目生成的ConsoleApp.exe,进行同样的操作,在打开Main()方法后会发现其中的代码与图6-2中几乎完全一样,如图6-3所示

图片 4

图6-3方法体的CIL语言描述(C#)

至此,可以得到一个初步的推断:不管是VB.NET还是是C#,编译之后的程序集都能够用IL DASM打开,因此它们生成的程序集的格式都是相同的;当程序所实现的功能相同时,程序集所包含的CIL代码也是类似的。

现在对上面程序集中所包含的类似汇编的语言做一下介绍,即是本节标题中的CIL(Common Intermediate Language,公共中间语言)。CIL最初是随着.NET由微软一起发布的,因此之前也叫做MSIL(Microsoft Intermediate Language),后来进行了标准化,之后便被称做CIL。在一些书或文章中,CIL也会简写为IL,其实都是指同样的东西。为了避免混淆,本书统一用CIL这个缩写。

我们可以将上面的过程用图6-4来表示出来。

图片 5

图6-4 源程序编译为了程序集

接下来再深入地分析一下,公共中间语言这个术语到底包含了哪几层含义。

  • 公共。因为不论是C#语言也好,VB.NET语言也好,C++/CLI语言也好,甚至是重新开发的一套以自己的名字缩写命名的语言,只要它期望运行的目标平台是.NET,在经过相应的编译器编译之后,所生成的程序集就是由CIL语言代码描述的。
  • 中间。这个词也是大有深意,为什么不叫公共机器语言(Common Machine Language),或者公共本地语言(Common Native Language)?因为这种语言只是比我们使用的高级语言,比如C#低级一点,并不是CPU可以直接执行的本地机器语言。这种语言还需要.NET运行时(.Net runtime)环境的支持,在执行之前,进行一个被称为Just-in-time(即时)的二次编译过程,才能转变成计算机可以识别的指令。关于.NET运行时,以及详细过程后面再介绍,现在只要知道,这个文件所包含的CIL代码并非机器可以直接执行的指令代码。
  • 语言。CIL不过是一种程序语言,只不过相对于C#来说,它是一种更低级语言。从图6-2 的代码截图中,已经可以看到,CIL是一种基于堆栈的语言,同时,它提供了class、interface、继承、多态等诸多面向对象的语言特性,因此它又是完全面向对象的语言。如果愿意,甚至可以直接编写CIL代码,并且使用CIL的编译工具IL ASM(IL Assembler,IL汇编程序)来对它进行编译。只不过,和大多数低级语言一样,这种方式会使开发效率会变得很低。这里注意区别一下IL ASM和IL DASM,它们的拼写是不同的。

为了加深一下印象,我们来做一个试验:编写一段简单的CIL代码,并且使用IL ASM工具对其进行编译,得到和前面一样的ConsoleApp.exe程序。

1)打开记事本程序,输入下面的代码,然后将其保存在D:ConsoleApp.il。

.assembly extern mscorlib{}
.assembly ConsoleApp{}
.module ConsoleApp.exe
.class public auto ansi Program extends System.Object
{
    .method public static void Main()
    {
        .entrypoint
        nop
        ldstr "Hello, World!"
        call void [mscorlib]System.Console::WriteLine(string)
        nop
        ret
    }
}

2)打开Visual Studio 2010命令行工具,输入:

D:>ilasm ConsoleApp.il

3)成功后会看到ConsoleApp.exe程序,它的执行结果和上面用C#编写的完全一样。

由于程序集是由CIL语言所描述的,因此CIL也叫做程序集语言(Assembly Language)。又因为.NET程序集需要由.NET运行时加载才能运行,可以视其为由.NET运行时进行管理的,所以CIL代码也叫做托管代码(Managed Code)。相对的,不需要.NET运行时就可以执行的代码就叫做非托管代码(Unmanaged Code)。

好了,已经知道了CIL的存在,从现在开始,最好在头脑里建立起两个模型或两种视角:一种是基于C#或其他高级语言的源程序的视角,一种是基于CIL中间语言的程序集视角。C#源程序在被编译为程序集以后,就独立于C#,因此程序集可以由其他种类的语言所调用;同时,因为程序集并没有包含本地机器的指令,所以它与具体的机器类型也分隔开了,可以被装有.NET框架的任何机器运行。

然而我高兴的还是太早了。这个扩展只支持了C#语言,VB.NET根本不如作者的法眼。好在这个扩展是开源的,顺着扩展的介绍页面找到了他的github页面 (可怜目前为止只有2个star,1个fork,其中一个star是我点的,唯一的fork也是我拉了个分支,可见微软的技术在开源社区是何等的冷清),通过阅读 TameVisualStudioEditorToolTips/TameQuickInfo.cs 的代码发现没有对vb.net的支持,这是15、16、17行的代码:

在 .NET Core 中使用 EntityFramework + Sqlite

.NET Core 中的 EntityFramework 也在 RC2 也有较大的变化。包的名字从 "EntityFramework." 变化为 "Microsoft.EntityFrameworkCore."。
如需使用Sqlite的话,project.json的包依赖应该为:

"dependencies": {
    ...
    ...
    "Microsoft.EntityFrameworkCore": "1.0.0-*",
    "Microsoft.EntityFrameworkCore.Sqlite": "1.0.0-*",
    "Microsoft.NETCore.App": {
        "type": "platform",
        "version": "1.0.0-rc2-*"
    }
}

另外,frameworks 节点对 netcoreapp1.0 也需增加新的imports (portable-net45+win8+wp8+wpa81 和 portable-net45+win8+wp8):

"frameworks": {
    "netcoreapp1.0": {
        "imports": [
            "portable-net45+wp80+win8+wpa81+dnxcore50",
            "portable-net45+win8+wp8+wpa81",
            "portable-net45+win8+wp8"
        ]
    }
}

然后在Startup.cs中注册EF相关的服务和DbContext:

public void ConfigureServices(IServiceCollection services)
{
    services.AddEntityFramework()
            .AddEntityFrameworkSqlite()
            .AddDbContext<WebsiteDbContext>(
                options => options.UseSqlite("Data Source=./mvcefsample.sqlite")); //设置链接字符串

    services.AddMvc();
}

再到Configure里面初始化数据库或者启用DbMigration:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        ...

        using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            var db = serviceScope.ServiceProvider.GetService<WebsiteDbContext>();

            // do db migrate automatically
            // db.Database.Migrate();

            if (db.Database.EnsureCreated())
            {
                for (int i = 0; i < 10; i++)
                {
                    var article = new Article {
                        Title = string.Format("Article {0}",  i + 1),
                        Content = string.Format("Article {0} content blabla blabla",  i + 1),
                        CreatedTime = DateTime.Now,
                        UpdatedTime = DateTime.Now
                    };

                    db.Articles.Add(article);
                }
                db.SaveChanges();
            }
        }
    }

完整示例可参考我在github上的示例项目:

    [ContentType("CSharp")]
    [ContentType("XAML")]
    [ContentType("XML")]

在 ASP.NET MVC Core 中使用 ASP.NET Identity

  1. ASP.NET 中身份验证是免不了的事情,首先第一步在 project.json 中添加包依赖:

    "dependencies": {
        ...
        ...
        "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0-*",
        ...
        "Microsoft.EntityFrameworkCore": "1.0.0-*",
        "Microsoft.EntityFrameworkCore.Sqlite": "1.0.0-*",
        "Microsoft.NETCore.App": {
            "type": "platform",
            "version": "1.0.0-rc2-*"
        }
    }
    
  2. 实现带有 Identity 支持的 DbContext:

    using Microsoft.EntityFrameworkCore;
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    
    namespace MvcIdentitySample
    {
        public class ApplicationUser : IdentityUser
        {
    
        }
    
        public class WebsiteDbContext : IdentityDbContext<ApplicationUser>
        {
            public WebsiteDbContext(DbContextOptions<WebsiteDbContext> options)
                : base(options)
            {
    
            }
    
            //public DbSet<Article> Articles { get; set; }
        }
    }
    
  3. 然后在 Startup 中的 ConfigureSerivces 方法中注册服务:

    public void ConfigureServices(IServiceCollection services)
    {
        // register services about EF
        services.AddEntityFramework()
                .AddEntityFrameworkSqlite()
                .AddDbContext<WebsiteDbContext>(
                    options => options.UseSqlite("Data Source=./mvcidentitysample.sqlite"));
    
        // register services about ASP.NET Identity
        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<WebsiteDbContext>()
            .AddDefaultTokenProviders();
    
        services.AddMvc();
    }
    
  4. 再到 Startup 中的 Configure 方法中启用 Identity:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        ...
    
        // the authentication must be configured before mvc
        app.UseIdentity();
    
        // To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715
        /*
        app.UseFacebookAuthentication(new FacebookOptions
        {
            AppId = "901611409868059",
            AppSecret = "4aa3c530297b1dcebc8860334b39668b"
        });
        */
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
    

注意 app.UseIdentity() 这句必须放到启用 MVC 之前,否则 Identity 无法生效,这个问题折腾了我几个小时。:(

  1. 由于 ASP.NET MVC 6 和 最新的 ASP.NET Identity 的变化,其使用方法与老版本的模版代码略有不同。

    a. 页面头部登陆状态部分页面(/Views/Shared/_LoginPartial.cshtml),由于 taghelper 的引入和 模版引擎的变化,这个页面的代码看起来会和以前有明显的不同:

    @using Microsoft.AspNetCore.Identity
    @using MvcIdentitySample
    @using MvcIdentitySample.Models
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @inject SignInManager<ApplicationUser> SignInManager
    @inject UserManager<ApplicationUser> UserManager
    
    @if (SignInManager.IsSignedIn(User))
    {
        <form asp-controller="Account" asp-action="LogOff" method="post" id="logoutForm" class="navbar-right">
            <ul class="nav navbar-nav navbar-right">
                <li>
                    <a asp-controller="Manage" asp-action="Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
                </li>
                <li>
                    <button type="submit" class="btn btn-link navbar-btn navbar-link">Log off</button>
                </li>
            </ul>
        </form>
    }
    else
    {
        <ul class="nav navbar-nav navbar-right">
            <li><a asp-controller="Account" asp-action="Register">Register</a></li>
            <li><a asp-controller="Account" asp-action="Login">Log in</a></li>
        </ul>
    }
    

    b. 新增 _ViewImports.cshtml (/Views/_ViewImports.cshtml) 的使用避免了重复在多个view里面增加相同的using和其它定义:

    @using Microsoft.AspNetCore.Identity
    @using MvcIdentitySample
    @using MvcIdentitySample.Models
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    

    这样就不用在刚才的_LoginPartial.cshtml页面里增加同样的代码了。

然后克隆这个项目,加上Basic、HTML、CSS、Jscript的支持

总结

大家通过以上介绍和示例应该可以了解到,当前使用.NET Core 来进行简单的应用开发是可行的,dot cli(dotnet) 这个工具已经比上个版本(RC1)的工具简单方便了很多,而且统一的Web开发和Console开发,CLI工具本身以后应该不会有太大的变化。因为.NET Core 1.0 RC2还在开发测试阶段,有的包可能还没有发布到NuGet上,因此而造成的找不到合适包的情况属于常见问题之一,不过只要在NuGet.config中增加了合适的Package Source,这个问题就很好解决了。所以大家如果想要把自己的项目,公司的项目迁移到.NET Core, 现在就可以开始动手了,不用再等到时间不确定的 1.0 release。

另外,本文所展示的示例代码限于篇幅与排版,无法做到十分详细,例如代码中所需要的using并未提及,还需要读者来自行添加(VS里ALT+SHIFT+F10, VSC里面好像只能手动点感叹号?)。

而且此文旨在尝试.NET Core的可用性,因此并未对如ASP.NET MVC 6和 EF7相关技术做深入探讨,如需了解请查看相关技术文档:

  1. ASP.NET MVC
  2. EntityFramework

最后再提醒大家一次,本文中所涉及的代码的完整示例项目已放到 github 上,欢迎大家fork/star/send pr:

namespace TameVisualStudioEditorToolTips {

    using System.ComponentModel.Composition;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Input;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.Shell;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Utilities;

    [Export(typeof(IAsyncQuickInfoSourceProvider))]
    [Name("Tame Quick Info")]
    [Order(Before = "Default Quick Info Presenter")]
    [ContentType("CSharp")]
    [ContentType("Basic")]
    [ContentType("XAML")]
    [ContentType("XML")]
    [ContentType("HTML")]
    [ContentType("CSS")]
    [ContentType("JScript")]
    internal class TameQuickInfo : IAsyncQuickInfoSourceProvider {

        public IAsyncQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer) {
            return textBuffer.Properties.GetOrCreateSingletonProperty(() => new CancelingQuickInfoSource());
        }
    }

    internal class CancelingQuickInfoSource : IAsyncQuickInfoSource {

        public CancelingQuickInfoSource() {
        }

        public void Dispose() {
        }

        public async Task<QuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken) {
            var isKeyDown = false;
            ThreadHelper.JoinableTaskFactory.Run(async delegate {
                // now on the UI thread
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                isKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) || Keyboard.IsKeyDown(Key.LeftCtrl)  || Keyboard.IsKeyDown(Key.RightCtrl);
            });

            // back on background thread
            if (!isKeyDown) {
                _ = session.DismissAsync();
            }
            return await System.Threading.Tasks.Task.FromResult<QuickInfoItem>(null);
        }
    }
}

在visual studio里编译,安装,最后大功告成!

本文由10bet手机官网发布于多线程,转载请注明出处:关闭鼠标悬停时自动出现快速文档浮层的方法,历险之旅

上一篇:捕获几个事件,各种手机的全局按键 下一篇:北京java培训班哪家好,编程语言学习哪种最有
猜你喜欢
热门排行
精彩图文