private void InitConfigFromFile() {
bool implicitSectionsAdded = false;
try {
// If initialization should be delayed, do not read the file.
if (ClassFlags[ClassSupportsDelayedInit] && Host.IsInitDelayed(this)) {
// determine the root of delayed initialization
if (_parent._initDelayedRoot == null) {
_initDelayedRoot = this;
}
else {
_initDelayedRoot = _parent._initDelayedRoot;
}
}
else {
//
// This parent of a record that is not initDelayed must also
// not be initDelayed.
//
Debug.Assert(!_parent.IsInitDelayed, "!_parent.IsInitDelayed");
using (Impersonate()) {
//
// Get the stream name. Note that this may be an expensive operation
// for the client configuration host, which is why it comes after the
// check for delayed init.
//
ConfigStreamInfo.StreamName = Host.GetStreamName(_configPath);
if (!String.IsNullOrEmpty(ConfigStreamInfo.StreamName)) {
// Lets listen to the stream
ConfigStreamInfo.StreamVersion = MonitorStream(null, null, ConfigStreamInfo.StreamName);
using (Stream stream = Host.OpenStreamForRead(ConfigStreamInfo.StreamName)) {
if (stream == null) {
// There is no stream to load from
return;
}
ConfigStreamInfo.HasStream = true;
// Determine whether or not to prefetch.
_flags[PrefetchAll] = Host.PrefetchAll(_configPath, ConfigStreamInfo.StreamName);
using (XmlUtil xmlUtil = new XmlUtil(stream, ConfigStreamInfo.StreamName, true, _initErrors)) {
ConfigStreamInfo.StreamEncoding = xmlUtil.Reader.Encoding;
// Read the factories
Hashtable factoryList = ScanFactories(xmlUtil);
_factoryRecords = factoryList;
// Add implicit sections before scanning sections
AddImplicitSections(null);
implicitSectionsAdded = true;
// Read the sections themselves
if (xmlUtil.Reader.Depth == 1) {
ScanSections(xmlUtil);
}
}
}
}
}
}
}
//
// Capture all exceptions and include them in _initErrors so execution in Init can continue.
//
catch (XmlException e) {
//
// Treat invalid XML as unrecoverable by replacing all errors with the XML error.
//
_initErrors.SetSingleGlobalError(
ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, ConfigStreamInfo.StreamName, 0));
}
catch (Exception e) {
_initErrors.AddError(
ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, ConfigStreamInfo.StreamName, 0),
ExceptionAction.Global);
}
catch {
_initErrors.AddError(
ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), null, ConfigStreamInfo.StreamName, 0),
ExceptionAction.Global);
}
//
// If there are global errors that make all input invalid,
// reset our state so that inherited configuration can still be used,
// including location sections that apply to this file.
//
if (_initErrors.HasGlobalErrors) {
//
// Parsing of a section may have been in progress when the exception
// was thrown, so clear any accumulated local errors.
//
_initErrors.ResetLocalErrors();
//
// Stop monitoring any configSource streams, but still continue
// to monitor the main config file if it was successfully monitored.
//
HybridDictionary streamInfos = null;
lock (this) {
if (ConfigStreamInfo.HasStreamInfos) {
streamInfos = ConfigStreamInfo.StreamInfos;
ConfigStreamInfo.ClearStreamInfos();
if (!String.IsNullOrEmpty(ConfigStreamInfo.StreamName)) {
StreamInfo fileStreamInfo = (StreamInfo) streamInfos[ConfigStreamInfo.StreamName];
// add this file's streaminfo to the now empty list
if (fileStreamInfo != null) {
streamInfos.Remove(ConfigStreamInfo.StreamName);
ConfigStreamInfo.StreamInfos.Add(ConfigStreamInfo.StreamName, fileStreamInfo);
}
}
}
}
// Stop monitoring streams outside the lock, to prevent deadlock.
if (streamInfos != null) {
foreach (StreamInfo streamInfo in streamInfos.Values) {
if (streamInfo.IsMonitored) {
Host.StopMonitoringStreamForChanges(streamInfo.StreamName, ConfigStreamInfo.CallbackDelegate);
}
}
}
// Remove file input
if (_sectionRecords != null) {
List<SectionRecord> removes = null;
foreach (SectionRecord sectionRecord in _sectionRecords.Values) {
if (sectionRecord.HasLocationInputs) {
// Remove any file input
sectionRecord.RemoveFileInput();
}
else {
// Remove the entire section record
if (removes == null) {
removes = new List<SectionRecord>();
}
removes.Add(sectionRecord);
}
}
if (removes != null) {
foreach (SectionRecord sectionRecord in removes) {
_sectionRecords.Remove(sectionRecord.ConfigKey);
}
}
}
// Remove all location section input defined here
if (_locationSections != null) {
_locationSections.Clear();
}
// Remove all factory records
if (_factoryRecords != null) {
_factoryRecords.Clear();
}
}
if (!implicitSectionsAdded) {
// Always add implicit sections no matter we have a file or not.
AddImplicitSections(null);
}
}