在开发Web或控制台应用程序时,经常需要访问诸如应用程序运行目录、托管环境版本或环境变量(如TEMP文件夹位置、PATH和USERPROFILE变量)等变量。也可能想要以一种不会在配置文件中出现的方式存储安全相关信息,如数据库密码或安全令牌,以防止这些信息被提交到源代码控制系统中。
在.NET 4.x中,使用了如AppDomain或ConfigurationManager.AppSettings这样的静态变量,这可能会根据应用程序运行的类型和环境引起各种问题。对于.NET可移植库,这种方式也不是很友好。
编写针对Core CLR的新应用程序时,这些构造不再可用,更重要的是,不再需要它们了。随着DNX的出现,ASP.NET团队为各种应用程序编写了一个出色的宿主环境,但它也带来了许多新概念。
例如,有多种方式可以访问应用程序正在运行的环境变量:
ASP.NET团队引入了一个轻量级的DI框架,DNX也使用它来将内容注入到应用程序中。注意:内置的DI框架仅支持构造函数注入。它可以被更重量级的包如Autofaq或Ninject替换。在本文中,将使用内置的DI。
DNX的一个优点是它可以将有用的数据注入到应用程序的入口点。对于ASP.NET Web应用程序,可以将其注入到Startup.cs的构造函数中,对于控制台应用程序,使用Program.cs的构造函数。
现在,问题是,需要注入什么以及如何工作?Microsoft.Framework.Runtime.Abstractions NuGet包提供了可以使用的接口。如果将其中一个接口添加到构造函数,宿主(DNX)将在运行时注入实例化的实现。
具体的实现可能会根据应用程序运行的环境(例如Windows或Linux)而有所不同。这就是依赖注入和新框架的美妙之处。在开发时不需要知道,更重要的是,不需要关心差异。
框架为抽象了这些差异,它就会工作。因为这些接口为提供了一个强类型的合同,可以期望这些属性是设置的。有几个接口提供了来自Microsoft.Framework.Runtime.Abstractions NuGet包的不同环境信息:
提示:还有更多接口,如ICompilerOptions或IAssemblyLoader,可能会非常有用,但这里不会讨论。自己尝试使用它们!
要编写一个ASP.NET 5控制台应用程序,请使用Visual Studio 2015(RC或更高版本)和新的ASP.NET 5项目模板创建一个控制台应用程序。这将创建一个针对新的DNX 4.5.1和DNX Core 5.0的项目.json,以及一个简单的Program.cs。
public class Program
{
public void Main(string[] args)
{
}
}
要在控制台应用程序中使用Microsoft.Framework.Runtime.Abstractions NuGet包,必须将其添加为项目.json文件的依赖项:
"dependencies": {
"Microsoft.Framework.Runtime.Abstractions": "1.0.0-beta6-*"
},
注意:版本可能会有所不同,在撰写本文时,它是beta6。在所有这些都发布之前,版本之间可能会有破坏性更改。确保所有框架和系统包都是相同的里程碑,例如不要混合beta 4和beta 5包。
另外,请确保运行的应用程序版本与安装的包版本相匹配。
现在,将这些接口作为参数添加到应用程序的构造函数中。在以下示例中,使用控制台输出来打印这些接口提供的某些信息:
public Program(IApplicationEnvironment app,
IRuntimeEnvironment runtime,
IRuntimeOptions options)
{
Console.WriteLine(
"ApplicationName: {0} {1}",
app.ApplicationName, app.Version);
Console.WriteLine(
"ApplicationBasePath: {0}",
app.ApplicationBasePath);
Console.WriteLine(
"Framework: {0}",
app.RuntimeFramework.FullName);
Console.WriteLine(
"Runtime: {0} {1} {2}",
runtime.RuntimeType, runtime.RuntimeArchitecture, runtime.RuntimeVersion);
Console.WriteLine(
"System: {0} {1}",
runtime.OperatingSystem, runtime.OperatingSystemVersion);
}
public void Main(string[] args) { ... }
ASP.NET 5还带来了一个新的配置框架。不会详细说明它是如何替代app/web.config的。但总的来说,它是一个基于字符串的键值对集合。
主要的NuGet包Microsoft.Framework.Configuration带有ConfigurationBuilder类,可以用来将不同的配置源组合成一个键值对集合。
随后的包,如Microsoft.Framework.Configuration.EnvironmentVariables和Microsoft.Framework.Configuration.Json,为ConfigurationBuilder添加了扩展方法,以便访问特定的配置源。
对于示例,想要检索所有环境变量,如PATH或USERPROFILE,并打印键和值到控制台输出。
除了上面提到的Microsoft.Framework.Runtime.Abstractions之外,还在project.json文件中添加了一个对Microsoft.Framework.Configuration.EnvironmentVariables的依赖引用。
"dependencies": {
"Microsoft.Framework.Runtime.Abstractions": "1.0.0-beta6-*",
"Microsoft.Framework.Configuration.EnvironmentVariables": "1.0.0-beta6-*",
...
},
在这个包中已经有了对Microsoft.Framework.Configuration的依赖,这意味着不必显式引用它。
在应用程序构造函数中,现在可以实例化一个新的ConfigurationBuilder并调用扩展方法。
var configuration =
new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
要将所有变量打印到控制台,可以简单地遍历所有可用的键值对。
foreach(var config in configuration.GetConfigurationSections())
{
Console.WriteLine("{0}={1}", config.Key, configuration.Get(config.Key));
}
还有另一种称为用户机密的东西。用户机密是从应用程序的上下文实例化的用户帐户的配置文件中检索的,例如在Windows上的%APPDATA%\microsoft\UserSecrets\
有关如何配置用户机密的更多信息,请访问ASP.NET wiki页面。概念与上述环境变量相同,可以通过调用ConfigurationBuilder上的AddUserSecrets扩展将配置的用户机密添加到键值对集合中。