关于.NET中配置文件

对于程序开发者而言,写配置文件是经常性的工作,如果你写了一个xx.config文件,如果没有详尽的注释,别人恐怕很难读懂,没有良好的配置架构,程序也失去了活力。在我看来,.net配置文件的特点在于反射定义和继承性。

 

SDK中<:SECTION>的定义为:

我们来看看.net框架内是如何利用这种结构的。反编译System.dll找到GetConfig方法,在里面我们发现实际获取config的工作默认是由实现了IConfigurationSystem的DefaultConfiguationSystem类来实现的。

public static object GetConfig(string sectionName)

{

if (!ConfigurationSettings._configurationInitialized)

{

lock (typeof(ConfigurationSettings))

{

if ((ConfigurationSettings._configSystem == null) && !ConfigurationSettings.SetConfigurationSystemInProgress)

{

ConfigurationSettings.SetConfigurationSystem(new DefaultConfigurationSystem());

}

}

}

if (ConfigurationSettings._initError != null)

{

throw ConfigurationSettings._initError;

}

return ConfigurationSettings._configSystem.GetConfig(sectionName);

}

<:SECTION style="TEXT-INDENT: 2em"

name="section name"

type="configuration section handler class, assembly"

allowDefinition="Everywhere|MachineOnly|MachineToApplication"

allowLocation="true|false" />

的定义为:

name="section group name"/>

 

我们再来看DefaultConfigurationSystem,这个类主要包含了machine.config的名称路径的基本信息和一些uri操作,而实际的GetConfig的操作交给了ConfiguationRecord来处理,这个类没有实现任何接口,可见他和DefaultConfiguration是绑定在一起的。

1internal class DefaultConfigurationSystem : IConfigurationSystem

2{

3 // Methods

4 internal DefaultConfigurationSystem();

5 object IConfigurationSystem.GetConfig(string configKey);

6 void IConfigurationSystem.Init();

7

8 // Properties

9 internal static Uri AppConfigPath { get; }

10 internal static string MachineConfigurationFilePath { get; }

11 internal static string MsCorLibDirectory { get; }

12

13 // Fields

14 private ConfigurationRecord _application;

15 private const string ConfigExtension = "config";

16 private const string MachineConfigFilename = "machine.config";

17 private const string MachineConfigSubdirectory = "Config";

18 private const int MaxPathSize = 0x400;

19}

20

事实上所有的配置文件的分析和获取都是在ConfiguationRecord里实现的,作为配置文件分析的第一步,正如我们经常做的一样->加载一个配置文件,这个方法公开为 Load(filename)。DefaultConfiguationSystem的Init()方法中用machine.config创建了一个ConfiguationRecord对象,并将其作为父对象传递给当前程序的ConfiguationRecord对象,当然前提是当前程序有配置文件,比如myapp.config,然后再加载当前程序的配置文件,从而实现配置文件的继承。

void IConfigurationSystem.Init()

{

lock (this)

{

if (this._application == null)

{

ConfigurationRecord record1 = null;

string text1 = DefaultConfigurationSystem.MachineConfigurationFilePath;

Uri uri1 = DefaultConfigurationSystem.AppConfigPath;

this._application = record1 = new ConfigurationRecord();

bool flag1 = record1.Load(text1);

if (!flag1 || (uri1 == null))

> {

return;

}

this._application = new ConfigurationRecord(record1);

this._application.Load(uri1.ToString());

}

}

}

现在我们可以专注于configuationrecord的具体实现了,load方法中得到一个XMLtextwriter,并执行.scanfactoriesrecursive和scansectionsrecursive方法。

reader1 = ConfigurationRecord.OpenXmlTextReader(filename);

if (reader1 != null)

{

this.ScanFactoriesRecursive(reader1);

if (reader1.Depth == 1)

{

this.ScanSectionsRecursive(reader1, null);

}

return true;

}

scanfactoriesrecursive方法会调用他的一个重载方法来解析中的,<:SECTION>,,,我们写配置文件时大小写可不能写错哦,.net没有做toslower之类的转换,直接就是 “== “。在这个方法里程序会将解析得到的sectiongroup以key=tagkey,value= ConfigurationRecord.GroupSingleton的方式存到EnsureFactories里,将section以key=tagkey,value=typestring的方式储存,值得注意的是,这里并没有创建实现IConfigurationSectionHandler的实例对象,而是将其类型名(比如:字符串”system.Configuration.NameValueSectionHandler”)作为值到EnsureFactories,等到后面GetConfig的时候再来反射创建。则存为ConfigurationRecord.RemovedFactorySingleton。就清空EnsureFactories。这里的tagkey是各级name的组合,比如”mygroup/mysection”这样以分隔符”/”组合的形式。应该客观地说这部分代码用了很多goto语句,可读性不是太好,但这样写也确实没有什么问题。

this.CheckRequiredAttribute(text3, "name", reader);

this.CheckRequiredAttribute(text4, "type", reader);

this.VerifySectionName(text3, reader);

string text5 = ConfigurationRecord.TagKey(configKey, text3);

if (this.HaveFactory(text5) != ConfigurationRecord.HaveFactoryEnum.NotFound)

{

objArray1 = new object[] { text3 } ;

throw this.BuildConfigError(SR.GetString("Tag_name_already_defined", objArray1), reader);

}

this.EnsureFactories[text5] = text4;

goto Label_02B6;

scansectionsrecursive方法会解析配置文件里的section实例,并将其tagkey储存到hashtable _unevaluatedSections中,表示尚未evaluated的configkey的集合,可见section实例对象的创建和handler一样,都是fetch when need。在后面的操作Getconfig中会使用他。

if (this._unevaluatedSections == null)

{

this._unevaluatedSections = new Hashtable();

}

this._unevaluatedSections[text2] = null;

现在我们就可以看getconfig方法是怎么来执行得到我们想要的对象的。

public object GetConfig(string configKey)

{

if (this._error != null)

{

throw this._error;

}

if (this._results.Contains(configKey))

{

return this._results[configKey];

}

object obj1 = this.ResolveConfig(configKey);

lock (this._results.SyncRoot)

{

this._results[configKey] = obj1;

}

return obj1;

}

如果_result中有对应configkey的section实例,就返回,没有则需要对configkey进行resolveconfig,将解析到的对象保存到_result中并返回给用户。在resolveconfig方法中,可以看到如果当前的配置文件中没有要求的configkey就会返回父级的section实例,比如machine.config里的内容。

public object ResolveConfig(string configKey)

{

Hashtable hashtable1 = this._unevaluatedSections;

if ((hashtable1 != null) && hashtable1.Contains(configKey))

{

return this.Evaluate(configKey);

}

if (this._parent != null)

{

return this._parent.GetConfig(configKey);

}

return null;

}

然后就是evaluate及其后续操作了,主要就是将configkey分解成字符串数组,一层层地去找对应的xmlelement,找到后传给configkey对应的handler,如果该handler没有创建则反射创建,然后由该handler创建section的实例对象,返回给用户,该部分关键代码如下:

ConfigXmlDocument document1 = new ConfigXmlDocument();

document1.LoadSingleElement(this._filename, reader);

config = factory.Create(config, null, document1.DocumentElement);

现在我们就明白了当我们用system..configurtion.configuationsetting.getconfig的时候发生过什么了。

我们访问配置文件时经常觉得配置文件的结构不太符合我们的需要,我们需要从里面更方便地获得自己定义的对象,而不仅仅是key和value,对于自定义配置文件的著述已有很多,在此不再描述,有兴趣的朋友可以访问。

转载于:https://www.cnblogs.com/win7xt/archive/2013/05/31/3110283.html

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值