饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 116 页

作者:Nick Randolph/等 当前章节:15385 字 更新时间:2026-6-18 14:51

process the section, and a class implementing this interface often resorted to parsing the XML block

to determine settings.

Visual Studio 2010 provides much better support for creating custom configuration sections via the

ConfigurationSection and ConfigurationElement classes. These provide the bases for creating

classes that map to the structure of the data being stored in the configuration files. Instead of

mapping a class that processes the configuration section, you can now create a much simpler class

786

.

chaPter 36 conFigurATion FileS

that maps to the section. When the section is referenced in code, an instance of this class is returned

with the appropriate data elements set. All the XML processing that would have been necessary in

the past is now handled by the .NET Framework.

Although this mapping makes the process of writing a custom configuration section much easier, you

may sometimes want more control over how the section is read. Two options can be used to give

you this control:

.

The first option is to go back to using a configuration section handler and manually process

the XML file. This can be useful if the original XML representation is required. However, it

still requires that the XML file be processed.

.

The second strategy is to create an appropriate mapping class as an in-between measure.

Instead of referencing this class directly, another class can be generated that exposes the

configuration information in the right way.

If you need to use either of these options, it might be worth taking a step back and determining

whether the configuration section structure is actually in a format suited to the data being stored.

In the following example your application requires a list of registered entities with which to work.

One type of entity is a company, and you need to be provided with both the company name and the

date on which it was registered. The XML snippet that you would like to have in the configuration

file might look like the following:

<RegisteredEntities>

<Companies>

<add CompanyName="Random Inc" RegisteredDate="31/1/2005" />

<add CompanyName="Developer Experience Inc" RegisteredDate="1/8/2004" />

</Companies>

</RegisteredEntities>

Once generated, the corresponding classes that would map to the preceding snippet might look like

the following (again, this requires a reference to the System.Configuration assembly):

Vb

Public Class RegisteredEntities

Inherits ConfigurationSection

<ConfigurationProperty("Companies")> _

Public ReadOnly Property Companies() As Companies

Get

Return CType(MyBase.Item("Companies"),Companies)

End Get

End Property

End Class

<ConfigurationCollectionAttribute(GetType(Company))> _

Public Class Companies

Inherits ConfigurationElementCollection

Protected Overrides Function CreateNewElement() As ConfigurationElement

Return New Company

application settings .

787

End Function

Protected Overrides Function GetElementKey _

(ByVal element As ConfigurationElement) As Object

Return CType(element, Company).CompanyName

End Function

Public Sub Add(ByVal element As Company)

Me.BaseAdd(element)

End Sub

End Class

Public Class Company

Inherits ConfigurationElement

<ConfigurationProperty("CompanyName",DefaultValue:="Random Inc",

IsKey:=true, IsRequired:=true)> _

Public Property CompanyName() As String

Get

Return CType(MyBase.Item("CompanyName"),String)

End Get

Set

MyBase.Item("CompanyName") = value

End Set

End Property

<ConfigurationProperty("RegisteredDate",DefaultValue:="31/1/2005",

IsKey:=false, IsRequired:=false)> _

Public Property RegisteredDate() As String

Get

Return CType(MyBase.Item("RegisteredDate"),String)

End Get

Set

MyBase.Item("RegisteredDate") = value

End Set

End Property

End Class

Code snippet RegisteredEntities.vb

c#

class RegisteredEntities : ConfigurationSection{

[ConfigurationProperty("Companies")]

public Companies Companies{

get{

return base["Companies"] as Companies;

}

}

}

[ConfigurationCollection(typeof(Company))]

class Companies : ConfigurationElementCollection{

788 .

chaPter 36 conFigurATion FileS

protected override ConfigurationElement CreateNewElement(){

return new Company();

}

protected override object GetElementKey

(ConfigurationElement element){

return (element as Company).CompanyName;

}

public void Add(Company element){

BaseAdd(element);

}

}

class Company : ConfigurationElement{

[ConfigurationProperty("CompanyName", DefaultValue = "Random Inc",

IsKey = true, IsRequired = true)]

public string CompanyName{

get{

return base["CompanyName"] as string;

}

set{

base["CompanyName"] = value;

}

}

[ConfigurationProperty("RegisteredDate", DefaultValue = "31/1/2005",

IsKey = false, IsRequired = true)]

public string RegisteredDate{

get{

return base["RegisteredDate"] as string;

}

set{

base["RegisteredDate"] = value;

}

}

}

Code snippet RegisteredEntities.cs

The code contains three classes that are required in order to correctly map the functionality of

this section. The registered entities section corresponds to the RegisteredEntities class, which

contains a single property that returns a company collection. A collection is required here because

you want to be able to support the addition of multiple companies. This functionality could be

extended to clear and/or remove companies, which might be useful if you had a web application

for which you needed to control which companies were available to different portions of the

application. Lastly, there is the Company class that maps to the individual company information

being added.

To access this section from within the code, you can simply call the appropriate section using the

configurationManager framework class:

application settings .

789

Vb

Dim registered as RegisteredEntities= _

ctype(configurationmanager.GetSection("RegisteredEntities"),RegisteredEntities)

c#

var registered =

ConfigurationManager.GetSection("RegisteredEntities") as RegisteredEntities;

In order for the .NET configuration system to correctly load your configuration

file with the RegisteredEntities section you will also need to register this section

in the configSections. You can do this by adding < section name= “ Registered

Entities ” type= “ ConfigurationApplication.RegisteredEntities,

ConfigurationApplication, Version=1.0.0.0, Culture=neutral,

PublicKeyToken=null “ / > to the configSections immediately before the

< /configSections > tag.

automation Using sCDl

You just saw how custom configuration sections can be written and mapped to classes. Although

this is a huge improvement over writing section handlers, it is still a fairly laborious process that is

prone to error. Furthermore, debugging the configuration sections is nearly impossible because it’s

difficult to track what’s going wrong.

As part of another project to support ASP.NET developers, a development manager for the

ASP.NET team at Microsoft recognized that the process of creating these mapping classes was

mundane and could easily be automated. To this end, he created a small application entitled SCDL

(http://blogs.msdn.com/dmitryr/archive/2005/12/07/501365.aspx) that could take a snippet

of configuration data, such as the RegisteredEntities section discussed previously, and output

both the mapping classes and a schema file that represented the section supplied. Once generated,

this code can be included in the application. Furthermore, if the snippet of configuration data is to

be included as a non-compiled file within the solution, it is possible to automate the generation of

the mapping classes via a pre-build batch command. If changes need to be made to the structure

of the section, they can be made in the snippet. That way, the next time the solution is built the

mapping classes will be updated automatically.

intellisense

Even after you get the custom configuration sections correctly mapped, there is still no support

provided by Visual Studio 2010 for adding the custom section to the configuration file. Unlike the

rest of the configuration file, which has support for IntelliSense and will report validation issues,

your custom section will not be able to be validated.

To get IntelliSense and validation for your custom configuration section, you need to indicate

the structure of the configuration section to Visual Studio 2010. You can do this by placing an

appropriate schema (as generated by the SCDL tool) in the XML Schemas folder, which is usually

located at C:\Program Files\Microsoft Visual Studio 10.0\Xml\Schemas\. Unfortunately,

790

.

chaPter 36 conFigurATion FileS

this is where it gets a little bit more complex, because it is not enough to place the file in that

folder; you also need to tell it that the schema should be included in the catalog used for parsing

configuration files. To register your schema, follow these steps:

1 .

Generate your schema file from your configuration snippet:

Scdl.exe snippet.scdl snippet.vb snippet.xsd

2 .

Copy the schema file (in this case, snippet.xsd) to the schema folder.

3 .

Create a new text file called Config.xsd and include the following lines. Note that if your

schema is called something different, you should update these lines appropriately. You may

also add additional lines to include more than one schema. Do not remove the DotNetConfig

.xsd line because that will remove validation for the standard configuration sections.

<?xml version="1.0" encoding="utf-8" ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:include schemaLocation="DotNetConfig.xsd"/>

<xs:include schemaLocation="snippet.xsd"/>

</xs:schema>

4 .

Open Catalog.xml in a text editor and replace DotNetConfig.xsd with Config.xsd.

This effectively remaps the validation, and IntelliSense, for configuration files to

use Config.xsd instead of DotNetConfig.xsd. However, because this file sources both

DotNetConfig.xsd and your schema information, you will get validation for both your

configuration section and the standard configuration sections.

user settinGs

Because configuration files are commonly used to store settings that control how an application

runs, it is often necessary to be able to dynamically change these to suit the way an individual uses

the application. Rather than having to build an entirely different framework for accessing and

saving these settings, you can simply change the scope of your settings. Figure 36-5 illustrates that

on the Settings tab of the Project Properties page you can indicate whether you want a setting to

have Application or User scope.

fiGure 36-5

In essence, by changing the scope of a setting you are making the choice as to whether you want

the setting to be read-only — in other words, it applies to the application regardless of which user is

using the application — or read-write. When you access a project setting from code you will notice

that if you try to assign a value to an Application setting you will get a compile error, whereas with

a User setting you can assign a new value. Assigning a new value to the User setting only changes

the value for that setting for the duration of that application session. If you want to persist the new

value between sessions you should call the Save method on the designer-generated Settings object,

as shown in the following code snippet:

VB

Properties.Settings.Default.BackgroundColor = Color.Blue;

Properties.Settings.Default.Save();

Table 36-2 lists the other methods that are defined on the Settings object that may be useful when

manipulating User settings.

Table 36-2: Settings Objects Methods

Method Name Functionality

Save Persists the current value of the setting.

Reload Restores the persisted value of the setting.

Reset Returns the persisted, and in-memory, value of a setting to the

default value (this is the value you define during development in

the Settings tab of the Project Properties page). You do not need

to call Save after calling Reset.

Upgrade When versioning your application you can call Upgrade to upgrade

user settings to new values associated with your application. Note

that you may want to be discriminate on when you call this method

because you may inadvertently clear user settings.

(event) SettingChanging Event raised when a setting is about to change.

(event) PropertyChanged Event raised when a setting has changed.

(event) SettingsLoaded Event raised when settings are loaded from persisted values.

(event) SettingsSaving Event raised prior to current values being persisted.

When building an application that makes use of User-scoped settings it is important to test the

application as if you were using it for the first time. The first time you run your application there will

be no user-specific settings, which means your application will either use the values in the application

configuration file or the default values that are coded in the designer-generated file. If you have been

testing your application, the Synchronize button on the Settings tab of the Project Properties page

(shown in the top-left corner of Figure 36-5) will remove any user-specific settings that may have

been persisted during earlier executions of your application.

User Settings . 791

792 .

chaPter 36 conFigurATion FileS

referenced ProJects with settinGs

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页