本文要点
- ASP.NET Core 支持跨平台(window/macOS/Linux),跟 Azure 托管的 Windows 和 Linux 虚拟机非常匹配。
- ASP.NET Core 包括一个内置的容器,它支持构造函数注入。
- 在 ASP.NET Core 应用程序的启动类的 ConfigureServices 中配置该容器的服务
- Azure 资源管理器模板允许脚本化配置 Azure 虚拟机及其所需的软件
- Azure 应用程序服务将服务器维护的底层细节抽象出来,并让开发人员直接部署 ASP.NET 项目到 Azure。
随着.NET Core 2.0 的发布,微软拥有了通用、模块化、跨平台和开源的平台的下一个主要版本,该平台最初发布于 2016 年。.NET Core 已经被创建为拥有很多在目前发布的.NET 框架中可用的 API。最初创建它的目的是为下一代 ASP.NET 解决方案提供支持,但是现在成为许多其他场景的基础,包括 IoT、云以及下一代移动解决方案。在本系列文章中,我们将探讨.NET Core 的优点以及它如何不仅仅有益于传统的.NET 开发人员,还有益于所有需要把稳健、高性能和经济的解决方案带入市场的技术人员。
本文是《.NET Core 》系列文章的其中之一。您可以通过RSS 订阅以接收相关通知。
我最感兴趣的.NET Core 的特性之一是跨平台支持,无论是在开发期还是在运行期。对于.NET,您不再被限制于Windows。如今,您可以使用Linux 和macOS 进行开发和运行应用程序。还有,不再要求开发和运行平台相同,因此,您可以在Mac 上开发您的.NET Core 应用程序,然后部署到Windows 和Linux 服务器。
微软的云平台Azure
Azure 是微软的云平台,能出色地匹配.NET Core 应用程序,因为其拥有大量用于托管这些应用程序的基础设施和平台服务,以及广泛的跨平台支持。Azure 有一套基础架构服务,提供计算、存储和网络功能,使客户能够像管理传统数据中心的基础架构一样部署虚拟服务器。 这种方法为客户提供对托管应用程序的基础架构和操作系统配置的强大控制。 Azure 虚拟机支持多种版本的 Windows Server 和多种 Linux 版本,包括 Red Hat、CentOS、Suse 等。
在把您的.NET Core 应用程序部署到 Azure 之前,您需要在 Azure 中设置应用程序主机或运行。在 Azure 中,您可以有很多方法来部署基础架构和服务。最简单容易的入门方法是使用 Azure 门户网站。从该门户网站,您可以在市场上找到所需的服务,并通过一系列询问向导来配置和部署这些服务。如果您正在配置虚拟机,只要虚拟机处于运行状态了,就可以进行远程管理和配置了,如果运行在 Windows 中,就使用远程桌面(Remote Desktop);而如果运行在 Linux 中,则使用 SSH。
如果您跟我一样,是个 DevOps 的粉丝,也许喜欢自己尽可能地编写脚本,这样就可以做到可重复和精简的。Azure 资源管理(Azure Resource Manager,简称 ARM)模板允许您在 Azure 中自动部署服务。ARM 模板只是简单的 JSON 文件,定义了您希望部署的资源以及它们之间的关系。这些 ARM 模板很受欢迎,并且有个 GitHub repo,它含有数百个为许多服务、平台和配置准备的预置模板。您可以找到这些模板和这个 GitHub repo。
除了部署和配置 Azure 服务,您还可以使用 ARM 模板来配置操作系统,以及使用虚拟机扩展来安装其他依赖项。例如,如果您在 Ubuntu Linux 上设置一个 web 服务器,您就需要部署 Ubuntu Linux 虚拟机,然后部署一个像 Apache 的 web 服务器。利用自定义脚本虚拟机扩展,您能够在虚拟机完成部署后执行自定义脚本。利用这些自定义脚本,您可以做很多事,像安装其他服务以及类似 Apache 及 PHP 的应用程序服务器。您可以在 Azure Quickstart 模板 GitHub repo 中看到一个例子,它是用 Apache 部署 Ubuntu Linux 服务器 ARM 模板。在 GitHub 上呈现的 README.md 文件中,您可以点击“Deploy to Azure”按钮,如图 1 所示,以开始把选定模板部署到您的 Azure 订阅的过程。一旦您拥有 web 服务器,就可以在 Azure 中部署和运行 ASP.NET Core 应用程序了。
图1 – 拥有Apache GitHub README.md 的Ubuntu
创建一个ASP.NET Core 应用程序
现在是时候创建一个我们可以部署到Azure 的.NET Core 应用程序了。利用Visual Studio 2017,我使用ASP.NET Core 创建了一个简单的web API。由于那个新的Hello World! 网络应用程序看起来是个待办事项列表,我就创建了一个待办事项列表API。
首先,我在Visual Studio 中创建了一个新项目,选择了web 类别和ASP.NET Core Web Application 模板,如图2 所示。
图2 – Visual Studio 2017 新ASP.NET Core Web Application
创建项目之后,我添加了一个定义属性为待办事项列表的模型类,代码如图3 所示。我让它很简单,只创建了id 的属性和待办事项列表项的名称,以及一个用于跟踪该项是否完成的布尔量。
public class TodoItem { public string Id { get; set; } public string Name { get; set; } public bool IsComplete { get; set; } }
图 3 – TodoItem.cs 模型类
在创建数据访问类时,我喜欢使用仓储模式,因此,我为待办事项列表存储库创建了一个接口,如图 4 所示。这定义了所有我需要用于访问数据的方法,包括一个读取单个待办事项的 get 方法、一个返回所有待办事项列表项的 get 方法,还有用于添加、更新和删除待办事项列表项的方法。
public interface ITodoItemRepository { TodoItem Get(string id); IList<TodoItem> Get(); void Add(TodoItem item); void Update(TodoItem item); void Delete(string id); }
图 4 – ITodoItemRepository.cs 待办事项列表仓储模式接口
然后,我用实体框架(Entity Framework,简称 EF)创建了待办事项列表项目仓储接口的实现,如图 5 所示。这包括 EF 上下文类和使用该 EF 上下文的仓储类。
public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } } public class TodoItemRepository : ITodoItemRepository { private readonly TodoContext _context; public TodoItemRepository(TodoContext context) { _context = context; if (!_context.TodoItems.Any()) { _context.TodoItems.Add(new TodoItem { Name = "Item1" }); _context.SaveChanges(); } } public TodoItem Get(string id) { return _context.TodoItems.FirstOrDefault(t => t.Id == id); } public IList<TodoItem> Get() { return _context.TodoItems.ToList(); } public void Add(TodoItem item) { _context.TodoItems.Add(item); _context.SaveChanges();
图 5 – TodoContext.cs 和 TodoListRepository.cs
最后,我用图 6 中所示的代码为待办事项列表 web API 创建了控制器。该控制器只是使用 ITodoItemRepository 并执行恰当的数据访问方法。
[Produces("application/json")] [Route("api/Todo")] public class TodoController : Controller { private ITodoItemRepository _repository; public TodoController(ITodoItemRepository repository) { _repository = repository; } [HttpGet] public IEnumerable<TodoItem> Get() { return _repository.Get(); } [HttpGet("{id}", Name = "Get")] public TodoItem Get(string id) { return _repository.Get(id); } [HttpPost] public void Post([FromBody]TodoItem value) { _repository.Add(value); } [HttpPut("{id}")] public void Put(int id, [FromBody]TodoItem value) { _repository.Update(value); }
图 6 – TodoController.cs Web API 控制器
现在,我们已经完成了那些实现待办事项列表 web API 的类,接下来我们需要为我们的 web API 做些配置以让它工作。当我们创建 web API 控制器实现时,我提到我们在用 ITodoItemRepository,但是在审查代码后,您也许想知道 ITodoItemRepository 字段是如何获取实现实体框架的 TodoItemRepository 实例的。ASP.NET Core 具有内置依赖注入容器支持运行时注入实现,并且可以调用 Startup.cs 中的 ISserviceCollection.Add* 方法,如图 7 所示,我们可以把 ITodoItemRepository 接口与 TodoItemRepository 类关联起来,因此,无论何时需要一个 ITodoItemRepository 类型的字段,都可以用 TodoItemRepository 实现的实例对其进行初始化。在这种情况下,我们使用 AddScoped() 方法,为每个请求创建一个新实例,并推荐给实体框架。您可以阅读更多有关服务生命周期选项的信息。
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddDbContext<TodoContext>(opt => opt.UseInMemoryDatabase("TodoList")); services.AddScoped<ITodoItemRepository, TodoItemRepository>(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); } }
图 7 – Starup.cs
另一方面,我们需要配置的是实体框架的数据存储。对于我们简单的 Hello World! 待办事项列表 API,我选择使用内存数据库。在图 7 所示的 Startup.cs 中,调用 IServiceCollection.AddDbContext 为实体框架上下文配置内存数据库。
有了这个,您就能够按 F5 键在本地运行该应用程序了,并且可以使用 Visual Studio 进行调试。除了在 Windows 上运行外,您也可以在 macOS 或 Linux OS 上运行,然后,您也可以把它部署到 Azure 中的 Windows 或 Linux 虚拟机。
部署到 Azure PaaS
作为开发人员,我们不想操心部署、配置和管理服务器。相反,我们宁愿把时间和精力专注于开发我们的应用程序上。虽然我们可以用底层基础架构服务,但 Azure 提供了很多高级平台服务,让开发人员专注于其应用程序和数据,从而减少花在设置和配置基础架构上的时间。对于客户来说,也不必一直为操作系统和应用程序服务器打补丁和进行维护了。
Azure 应用程序服务(Azure App Service)属于高级平台服务,可以把服务器和基础架构抽象并隐藏起来,只为我们提供一个部署我们网络应用程序的目标。在 Visual Studio 中,您可以在 ASP.NET 项目上单击右键,选择 Publish 选项,如图 8 所示,以启动把您的网络应用程序部署到 Azure 应用程序服务中的网络应用程序。
图8 – 高亮显示Publish 选项的Visual Studio 项目上下文菜单
选择Publish 选项后,Visual Studio 中的一个屏幕会显示将要提供的几个部署目标选项,其中Azure App Service 是该列表上的第一个选项,如图9 所示。
图9 – Visual Studio 中的发布(Publish)屏幕
如果您选择Azure 应用程序服务,可以选择是否要通过“Create New”选项来创建一个全新的网络应用服务,或者可以通过选择“Select Existing”选项,在您的Azure 订阅中选择一个现有的网络应用程序。完成之后,可以点击“Publish”按钮以启动通过引导进行部署的流程。这将部署到默认的运行于Windows 上的Azure 应用程序服务,但是,现在您可以部署到运行于Linux 上的Azure 应用程序服务,甚至可以使用Docker 容器。
在Visual Studio 中,您可以轻松地启用Docker 容器支持您的ASP.NET Core 应用程序,只需要在您的ASP.NET Core 项目上单击右键而已,在上下文菜单中选择Add,然后选择Docker Support,如图10 所示。
图10 – 把Docker Support 添加到ASP.NET Core Apps
然后,Visual Studio 会显示一个对话框,让您来选择是否需要Windows 或Linux Docker 容器。在您选择了平台之后,Visual Studio 在您的项目中添加一个Dockerfile,并在包含多个docke-rcompose.yml 文件的解决方案资源管理器(Solution Explorer)中添加一个docker-compose 节点。
现在,在项目上单击右键选择发布(Publish)时,您会看到一些不同的选择,包括微软Azure 应用程序服务Linux 和容器注册表(Container Registry),如图11 所示。
图11 – 在Visual Studio 中的发布(Publish)屏幕,用于Docker 支持的ASP.NET Core web 应用程序
当您选择微软Azure 应用程序服务Linux 时,它将引导您完成部署流程,该过程将创建一个运行于Linux 上的Azure 应用服务程序,并具有docker 支持,您也可以选择创建或使用现有的docker 容器注册表。
Azure 是一个大型云平台,包含很多服务,我已经在本文中提到了像虚拟机这样的基础架构服务,以及像应用程序服务这样的平台服务,但是,在其他应用程序运行时,您还可以在 Azure 中运行的.NET Core 应用程序,包括 Azure Functions(无服务器)、Service Fabric(微服务)和 Azure Container Service(docker 容器)等等。如果您对这些服务感兴趣,可以访问 http://www.azure.com 以获得更多资讯。
结语
正如我在本文开头所提到的,我最喜欢的.NET Core 的特性之一是广泛的平台支持,包括 Windows、Linux 和 macOS。结合 Azure,您不仅获得跨平台的开发平台,还可以获得云平台以托管和运行支持很多操作系统(包括 Windows Server 和多个版本的 Linux)的应用程序,并且还有很多高级平台服务,像 Azure 应用程序服务、Docker 容器和拥有 Azure Functions 的无服务器计算。这种能力令人非常兴奋,并通过提供广泛的生态系统支持和开放性提供了很多可能性。
作者简介
Eric D. Boyd 是 responsiveX 的创始人兼 CEO。responsiveX 是一家管理和技术咨询公司,拥有深厚的行业和专业技能。通过对用户体验、创新及新兴平台的高度关注,responsiveX 的客户获得了战略合作伙伴,以帮助指导如今的开发工作,与此同时,为未来的创新准备。Eric 对技术、创业和业务增长充满激情。他喜欢开发创新和颠覆性的初创企业,发展现有业务,帮助他人提高技术投资的价值和回报。
阅读英文原文: https://www.infoq.com/articles/azure-and-net-core
感谢冬雨对本文的审校。
评论