Effective C#之Item 37:Use the Standard Configuration Mechanism

  rel="File-List" href="file:///C:%5CDOCUME%7E1%5CHelios%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml"> rel="themeData" href="file:///C:%5CDOCUME%7E1%5CHelios%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx"> rel="colorSchemeMapping" href="file:///C:%5CDOCUME%7E1%5CHelios%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml">

Item 37: Use the Standard Configuration Mechanism

使用标准的配置机制

In our quest to avoid hard-coding configuration and settings information, we have created many different strategies for storing configuration information. In our quest to get it right, we kept improving and changing our minds about where to put such information. INI files? That was so Windows 3.1. You were limited in the structure of your configuration information, and you had to contend with filename collisions with other applications. The Registry? Yes, this was a step in the right direction, but it had its limitations as well. Malicious programs could do serious damage to a machine writing the wrong things to the Registry. Because of the dangers inherent in writing to the Registry, a program must have administrative rights to write in parts of the Registry. Are all your users running as admins with the capability to edit the Registry? You hope not. If you use the Registry, users running as nonadmins will get exceptions and errors when they attempt to save or read their settings.

我们在寻求避免硬编码配置和信息设定的过程中,为存储配置信息已经创建了很多不同的策略。在寻求正解的过程中,我们不断的提高以及改进我们的想法,考虑将这些信息放到哪里。INI文件?在Windows 3.1里面是这样的。限制于配置文件的结构,你不得不处理和其它应用程序之间的文件名冲突。注册表?是的,这是在正确的方向迈出的一步,但是也有限制。恶意的程序,通过向注册表写入错误的东西,会对机器造成很大的毁害。因为写入注册表所固有的危险,一个程序必须有管理员权限才能向注册表的一部分进行写操作。你的所有用户都以管理员身份运行吗?都有编辑注册表的能力吗?不希望不是。如果你使用注册表,以非管理员身份运行的用户,尝试保存或者读取注册表时会遭遇异常和错误。

Thankfully, there are much better ways to store settings so that your program can adapt its behavior to your users' preferences, the install parameters, the machine settings, or just about anything else. The .NET Framework provides a standard set of locations that your application can use to store configuration information. These locations are specific to your application and will work when the user has limited privileges on the machine where the code executes.

让我们感到欣慰的是,存在更好的存储设置的方法,因此,你的程序可以调整它的行为来满足用户的参数选择、安装参数、机器设置或者其它任何东西。.Net框架提供了标准的位置集合,应用程序可以使用它们来存储配置信息。这些位置和应用程序相关,当程序被执行的机器上的用户被限制了权限时也可以工作。

Read-only information belongs in configuration files, XML files that control various types of behavior in the application. Defined schemas dictate all the elements and attributes that the .NET FCL parses from config files. These elements control settings such as the version of the framework being used, the level of debugging support (see Item 36), and the search path for assemblies. One section you must understand is the appSettings section, which applies to both web and desktop applications. The runtime reads this section when your application starts. It loads all the keys and values into a NameValueCollection owned by your application. This is your section. You add any values that your application needs to control its behavior. If you modify the config file, you modify the application's behavior.

只读信息属于配置文件,XML文件控制应用程序的各种行为。已定义的结构表指明了所有.Net由配置文件分析来的元素和属性,这些元素控制下面这样的设置:使用的框架的版本,调试支持的级别(Item 36),程序集的搜索路径。你必须理解的一个节点是appSettings,它可以同时用于web和桌面应用。当应用程序启动时,运行时读取该节点。它将所有的键/值加载到应用程序拥有的NameValueCollection中。这个节点是你控制的,可以向其中添加应用程序需要的任何值来控制它的行为。修改了配置文件,也就修改了程序的行为。

ASP.NET applications have a little more flexibility than desktop applications do with respect to config files. Each virtual directory can have its own config file. The files are read in order for each virtual directory that is part of the URL. The most local wins. For example, the URL http://localhost/MyApplication/SubDir1/SubDir2/file.aspx could be controlled by four different config files. The machine.config file gets read first. Second is the web.config file in the MyApplication directory. Following is the web.config files in SubDir1 and SubDir2, in that order. Each can change values set by a previous config file or add its own key/value pairs. You can use this configuration inheritance to set up global application preferences and limit access to some private resources. Web applications can have different configurations for different virtual directories.

在使用配置文件上,ASP.NET应用程序比桌面应用程序更灵活。每个虚拟目录都可以有它自己的配置文件。该文件被每个虚拟目录依次读取,每个虚拟目录对应一个URL的一部分。在大多数的本地windows系统中,例如,URLhttp://localhost/MyApplication/SubDir1/SubDir2/file.aspx可以被4个不同的配置文件控制。machine.config最先被读取,其次是位于MyApplication 目录的web.config,接下来就是位于SubDir1 SubDir2里面的web.config。它们就是按照这个顺序被访问的,每一个都可以修改前面配置文件已设定的值,或者添加自己的键/值对。你可以使用这个配置继承体系来设置全局应用程序的参数,对一些私有资源的访问做出限制。Web应用程序,在不同的虚拟目录上可以有不同的配置。

On the desktop, there is only one application configuration file for each app domain. The .NET runtime creates a default application domain for each executable that it loads, and reads one predefined config file into that domain. This default configuration file is located in the same directory as the executable and is called <applicationname>.<ext>.config. For example, MyApp.exe would have a config file named MyApp.exe.config. The appsettings section can be used to create your own key/value pairs for your application.

在桌面应用程序中,对每个应用程序域,仅仅有一个应用程序配置文件。.Net运行时为它加载的每个可执行程序创建一个默认的应用程序域,还为它读取一个预定义的配置文件。默认的配置文件被加载到和可执行程序同样的目录下面,命名方式是<applicationname>.<ext>.config(<应用程序名>. <扩展名>.config)。例如,MyApp.exe的配置文件的名字就是MyApp.exe.configappsettings部分可以被用来为应用程序创建你自己的键/值对。

Config files are great to store information that controls the behavior of your application at runtime. But you will quickly notice that there are no APIs to write configuration information from your application. Configuration files are not the place for user settings of any sort. Don't go running for the Registry yet. Don't write your own from scratch. There is a better way for your .NET desktop applications.

配置文件是存储一些信息的最好的地方,这些信息在运行时控制程序的行为。但是你很快就会注意到,你的应用程序并没有API来编写配置信息。配置文件不是放置任何用户设置的地方。先不要着急考虑注册表,也不要自己乱写。对于.Net桌面应用,有更好的方式。

You need to define the format for your configuration information and put that configuration information in the right location. You can easily store and retrieve these settings by defining a settings structure and adding public read/write properties for the global settings:

你需要定义配置信息的格式,将其放置在正确的位置。通过定义一个设置结构,并为这些全局设置添加公共读写属性,可以简单的存储和获取这些设置。

  1. [ Serializable( ) ]
  2. public struct GlobalSettings
  3. {
  4.   // Add public properties to store.
  5. }

Use the XML serializer to save your settings:

使用XML序列化来存储你的设置:

  1. XmlSerializer ser = new XmlSerializer( typeof( GlobalSettings ));
  2. TextWriter wr = new StreamWriter( "data.xml" );
  3. ser.Serialize( wr, myGlobalSettings );
  4. wr.Close( );
  5.  

Using XML format means that your settings will be easy to read, easy to parse, and easy to debug. You can use encrypted storage for these user settings, if necessary for your application. This example uses the XML serializer, not the object serializer for persistence (see Item 25). The XML serializer stores documents, not entire object trees. Configuration settings and user settings typically do not contain webs of objects, and the XML serializer is a simpler file format.

使用XML格式意味着你的设置容易读取,解析以及调试。如果应用程序需要的话,可以使用加密存储。这个例子为了持久性(Item 25),使用了XML序列化,而不是对象序列化。XML序列化存储文档,而不是整个对象树。配置设置和用户设置一般不会包含网状的对象结构,XML序列化是种简单的文件格式。

The only question remaining is where to store the information. You should put settings information in three different locations. Which you choose depends on when it should be used: Globally, per user, or per user and machine. All three locations are returned by different calls to by the System.Environment.GetFolderPath() method. You should append your application-specific directories on the end of the path returned by GetFolderPath(). Be extremely careful about writing information in the all-user or machine-wide directories. Doing so requires more privileges on the target machine.

唯一余留的一个问题就是在哪里存储这些信息。你可以把设置信息放在三个不同的位置。选择哪一个取决于它会在什么时候被使用:全局,每个用户,或者每个用户及机器。这3个位置可以通过对System.Environment.GetFolderPath()方法的不同调用获得。你应该在GetFolderPath()返回的路径后面添加上应用程序的详细目录。要格外小心的在所有用户或者机器范围上写信息。这要做需要在目标机器上获得更多特权。

Environment.SpecialFolder.CommonApplicationData returns the directory for storing information that is shared by all users on all machines. On a machine with a default installation, GetFolderPath (SpecialFolder.CommonApplicationData) returns C:/Documents and Settings/All Users/Application Data. Settings stored under this location should be used by all users, on all machines. When you create information that should go here, write it with the installer or an admin module. Avoid writing data here in your user programs. Chances are, your application does not have the necessary access rights on users' machines.

Environment.SpecialFolder.CommonApplicationData返回所有机器上所有用户共享的存储信息的目录。在一个机器上,如果使用默认安装,GetFolderPath (SpecialFolder.CommonApplicationData)会返回C:/Documents and Settings/All Users/Application Data。这个位置下存储的设置应该被所有用户在所有的机器上使用。当你创建应该放在那里的信息时,使用安装程序编写或者以管理员模式编写。避免在这里放置用户级别的数据,那样的话,偶然的时候,你的应用程序在用户机器上会没有必要的权限来进行访问。

Environment.SpecialFolders.ApplicationData returns the directory for this user, shared by all machines in the network. On a default installation, GetFolderPath(SpecialFolders.ApplicationData) gives you C:/Documents and Settings/<username>/Application Data. Each user has his or her own application data directory. When the user logs into a domain, using this enumeration points to the network share that contains the user's global settings. Settings stored under this location are used by the current user, no matter what machine in the network he has logged in from.

Environment.SpecialFolders.ApplicationData返回用户目录,在网络上被所有的机器共享。默认安装情况下,GetFolderPath(SpecialFolders.ApplicationData)返回C:/Documents and Settings/<username>/Application Data。每个用户都有自己的应用程序数据目录。当用户登陆到该域,使用该枚举。得到包含有用户全局设置的网络共享。存储在该位置下面的设置被当前的用户使用,而不用关心他从网络上的哪个机器来登陆。

Environment.SpecialFolders.LocalApplicationData returns the directory for storing information that is personal for this user and only when logged in on this machine. A typical value returned by GetFolderPath(SpecialFolders.LocalApplicationData) is C:/Documents and Settings/<username>/Local Settings/Application Data.

Environment.SpecialFolders.LocalApplicationData返回存储下列信息的目录:归某个用户使用并且只有当用户从该机器登陆时才使用。由GetFolderPath(SpecialFolders.LocalApplicationData)返回的典型值是 C:/Documents and Settings/<username>/Local Settings/Application Data.

These three different locations let you store settings that should apply to everyone, the given user, or the given user on the given machine. Exactly which you use depends on the application. But consider some obvious examples: The database connection is a global setting. It should be stored in the Common Application Data directory. A user's working context should be stored in the Application Data directory because it depends only on the user. Window locations should be in the Local Application Data directory because they depend on the user and properties of the machine (different machines might have different screen resolutions).

这三个不同的位置让你存储信息,能用应用到:单个用户、指定用户或者指定机器上的指定用户。你要使用哪一个,取决于应用程序。但是考虑一些明显的例子:数据库连接是全局设置,它应该被存储在Common Application Data目录下。一个用户的工作上下文应该被存储在Application Data目录下,因为它仅仅依赖于用户。窗口的位置应该在Local Application Data目录下,因为它们依赖于用户和机器的属性(不同的机器可能有不同的分辨率)

These special folders describe the top-level directory structure for user settings stored by all applications. In all cases, you should create subdirectories underneath these top-level structures. The .NET Framework's System.Windows.Application class defines properties that build common configuration paths for you. The Application.LocalAppDataPath property returns the path for GetFolderPath(SpecialFolders.CommonApplicationData)+"//CompanyName//ProductName//ProductVersion". Similarly, Application.UserDataPath and Application.LocalUserDataPath produce pathnames underneath the user's data and local data directories for this company, application, and version. If you combine these locations, you can create configuration information for all your company's applications, for this application across all versions, and for this specific version.

这些特定的文件夹描述了由所有应用程序存储的用户设置,这是一个顶级目录结构。在所有的情况下,你都应该在这些顶级结构下,创建子文件夹。.Net框架的System.Windows.Application类定义了你要构建通用配置路径要用的属性。Application.LocalAppDataPath属性返回由GetFolderPath(SpecialFolders.CommonApplicationData)//CompanyName//ProductName//ProductVersion组成的完整路径。类似的,Application.UserDataPathApplication.LocalUserDataPath产生该用户数据下的路径名字,以及公司、应用程序、版本的本地数据目录。如果你合并这些位置,你可以为你公司的所有应用程序、一个应用程序的所有版本、应用程序的特定版本创建配置信息。

Note that nowhere in those directories did I mention the application directory, under Program Files. You should not ever write data in any directory under Program Files or in the Windows system directory. Those locations require more security privileges, so you should not expect your users to have permission to write in them.

注意,在这些目录中,我从没有提到过应用程序目录,就是在Program Files下的目录。你决不应该在Program Files或者在Windows 系统目录里写数据。这些目录要更高的特权,因此你并不能指望你的用户有权利在这些地方进行读写。

Where you store your application's settings has become more important as everyone from enterprise users to home users worries about the security of machines. Putting the information in the right location means that it is easier for your users to work with your application without compromising security. You can still provide your users with a personalized experience. Combine the right location with .NET serialization, and it's easy to have your application provide a personalized appearance for each user without compromising security.

在哪里存储应用程序的设置成为很重要的问题,就像从每个企业级用户到每个家庭用户所担心的机器安全一样。把信息放在正确的位置就意味着,对于你的用户来说,没有折衷的办法。你还是要给用户提供个人的体验,用.Net的序列化组合正确的位置,这样可以很容易的给每个用户一种个人的感觉,而不用对安全问题进行折衷。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值