<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Christopher H. Laco &#187; configuration</title>
	<atom:link href="http://chrislaco.com/tag/configuration/feed/" rel="self" type="application/rss+xml" />
	<link>http://chrislaco.com</link>
	<description></description>
	<lastBuildDate>Wed, 28 Jul 2010 00:21:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Siphon Configuration</title>
		<link>http://chrislaco.com/articles/siphon-configuration/</link>
		<comments>http://chrislaco.com/articles/siphon-configuration/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 02:53:49 +0000</pubDate>
		<dc:creator>claco</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[siphon]]></category>

		<guid isPermaLink="false">http://chrislaco.com/?p=166</guid>
		<description><![CDATA[This is the second in a series of posts about Siphon, a set of data monitoring utilities for .NET under the MIT license. The source code can be found on GitHub. Introduction In this article, I&#8217;m going to cover how &#8230; <a href="http://chrislaco.com/articles/siphon-configuration/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the second in a series of posts about Siphon, a set of data monitoring utilities for .NET under the MIT license. The source code can be found on <a title="Siphon on GitHub" href="http://github.com/claco/siphon/">GitHub</a>.</p>
<h2><span id="more-166"></span>Introduction</h2>
<p>In this article, I&#8217;m going to cover how Siphon configuration works, the options and how to use the configuration classes to read/write configuration information.</p>
<h2>Configuration Section</h2>
<p>Here&#8217;s a sample Siphon configuration section from the source code:</p>
<pre class="brush:xml">&lt;configSections&gt;
  &lt;section name="siphon" type="ChrisLaco.Siphon.SiphonConfigurationSection, Siphon" /&gt;
&lt;/configSections&gt;

&lt;siphon&gt;
  &lt;monitors&gt;
    &lt;monitor name="IntervalMonitor" type="ChrisLaco.Siphon.LocalDirectoryMonitor, Siphon"&gt;
      &lt;settings&gt;
        &lt;add name="Path" value="C:\" /&gt;
        &lt;add name="Filter" value="*.tmp" /&gt;
      &lt;/settings&gt;
      &lt;schedule type="ChrisLaco.Siphon.IntervalSchedule, Siphon"&gt;
        &lt;interval value="1.2:3:4" /&gt;
      &lt;/schedule&gt;
      &lt;processor type="ChrisLaco.Siphon.DummyProcessor, Siphon" /&gt;
    &lt;/monitor&gt;
  &lt;/monitors&gt;
&lt;/siphon&gt;</pre>
<p>Let&#8217;s break this down piece by piece. First, we need to tell .NET who&#8217;s in charge of the siphon configuration section:</p>
<pre class="brush:xml">&lt;configSections&gt;
 &lt;section name="siphon" type="ChrisLaco.Siphon.SiphonConfigurationSection, Siphon" /&gt;
&lt;/configSections&gt;</pre>
<p>Next, we add a new monitor element to the monitors collection:</p>
<pre class="brush:xml">&lt;monitor name="IntervalMonitor" type="ChrisLaco.Siphon.LocalDirectoryMonitor, Siphon"&gt;</pre>
<p>Here we have a monitor named IntervalMonitor and told Siphon what type to load. If you&#8217;re not familiar with using type strings in .NET configuration,  the string above tells .NET that we want to use the class ChrisLaco.Siphon.LocalDirectoryMonitor in the Siphon assembly. Note that if you want to use types that are installed into the GAC you will need to use the full type string including the Culture, PublicKeyToken and Version.</p>
<p>Next, we configure setting required by the LocalDirectoryMonitor:</p>
<pre class="brush:xml">&lt;settings&gt;
  &lt;add name="Path" value="C:\" /&gt;
  &lt;add name="Filter" value="*.tmp" /&gt;
&lt;/settings&gt;</pre>
<p>The settings consist of name/value pairs that are passed to the monitors Initialize() method. The number of options and their values vary depending on the monitor being used. Next, we&#8217;ll tell the monitor how often to look for new data:</p>
<pre class="brush:xml">&lt;schedule type="ChrisLaco.Siphon.IntervalSchedule, Siphon"&gt;
  &lt;interval value="1.2:3:4" /&gt;
&lt;/schedule&gt;</pre>
<p>Just like with the monitor element above, we need to tell Siphon what schedule class we want to use. In our case, we&#8217;re going to use the IntervalSchedule, and set the interval using a string TimeSpan.Parse() understands: 1 day, 2 hours, 3 minutes and 4 seconds. If you are interested in a daily schedule, you can also use the daily element to specify a daily schedule:</p>
<pre class="brush:xml">&lt;schedule type="ChrisLaco.Siphon.DailySchedule, Siphon"&gt;
  &lt;daily&gt;
    &lt;time value="8:00" /&gt;
    &lt;time value="15:00" /&gt;
  &lt;/daily&gt;
&lt;/schedule&gt;</pre>
<p>Note: whether you use an interval or a daily schedule, the schedule type you use must understand the configuration you&#8217;ve chosen. As we&#8217;ll see in the Configuration classes later, the configuration format is setup to handle the most common use cases, like daily schedule values. Just like the monitor element, the schedule element also has a settings element used to pass name/value options to the specified schedule type.</p>
<p>Now that we&#8217;ve chosen a monitor and a schedule, the last thing to do is to tell Siphon who will process the newly found data as it arrives:</p>
<pre class="brush:xml">&lt;processor type="ChrisLaco.Siphon.DummyProcessor, Siphon" /&gt;</pre>
<p>Here we&#8217;ve loaded the DummyProcessor, which does does nothing with new data and always returns True. As with the monitor and schedule elements, the processor element also has a settings element collection.</p>
<h2>Reading Configuration</h2>
<p>Siphon comes with a set of classes to read/write siphon configuration data. Once you have finished setting up your app.config, you can use the SiphonConfigurationSection class to load the section and loop through all of the configured monitors:</p>
<pre class="brush:vb">REM Load config section: defaults to 'siphon'
Dim section As SiphonConfigurationSection = SiphonConfigurationSection.GetSection

REM Loop through monitor elements
For Each monitor As MonitorElement In section.Monitors

    REM Get a setting
    Dim path As String = monitor.Settings("Path").Value

    REM create an instance of the specified type
    Dim instance As IDataMonitor = monitor.CreateInstance
    instance.Path = path

    REM Set the schedule
    instance.Schedule = monitor.Schedule.CreateInstance

    REM Set the processor
    instance.Processor = monitor.Processor.CreateInstance

    REM Process new data
    instance.Process()
Next</pre>
<p>The code above is pretty straight forward. One item of interest: when CreateInstance is called, it creates an instance of the specified type and calls the Initialize() method on the new instance. While we set the Path setting manually, the monitors Initialize() could have also done the same thing.</p>
<p>All monitors must implement the IDataMonitor interface. All schedules must implement the IMonitorSchedule interface and all processors must implement the IDataProcessor interface. CreateInstance() looks for a constructor with no parameters in the type being created.</p>
<h2>Writing Configuration</h2>
<p>You can also use the configuration classes to programaticaly create configuration files. SImply create the settings in code, then save the config to the specified file:</p>
<pre class="brush:vb">Dim config As Configuration = ConfigurationManager.OpenExeConfiguration("C:\Path\To\SomeApp.exe")
Dim section As New SiphonConfigurationSection
Dim monitor As New MonitorElement("TestMonitor", "LocalDirectoryMonitor, Siphon")

monitor.Settings.Add(New NameValueConfigurationElement("Path", "C:\"))
monitor.Processor = New ProcessorElement("MockProcessor, SiphonTests")
monitor.Processor.Settings.Add(New NameValueConfigurationElement("Foo", "Bar"))
monitor.Schedule.Type = "IntervalSchedule, Siphon"
monitor.Schedule.Daily.Add(New TimeElement(New TimeSpan(100)))
monitor.Schedule.Daily.Add(New TimeSpan(200))
section.Monitors.Add(monitor)

config.Sections.Add("siphon", section)
config.Save()</pre>
<p>This will update the app.config file for the specified executable path with the new configuration information. The code above will generate something like this:</p>
<pre class="brush:vb">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;configuration&gt;
    &lt;configSections&gt;
        &lt;section name="siphon" type="ChrisLaco.Siphon.SiphonConfigurationSection, Siphon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0576062738dd7ad9" /&gt;
    &lt;/configSections&gt;
    &lt;siphon&gt;
        &lt;monitors&gt;
            &lt;monitor name="TestMonitor" type="LocalDirectoryMonitor, Siphon"&gt;
                &lt;schedule type="IntervalSchedule, Siphon"&gt;
                    &lt;interval value="00:01:00" /&gt;
                    &lt;daily&gt;
                        &lt;time value="00:00:00.0000100" /&gt;
                        &lt;time value="00:00:00.0000200" /&gt;
                    &lt;/daily&gt;
                &lt;/schedule&gt;
                &lt;processor type="MockProcessor, SiphonTests"&gt;
                    &lt;settings&gt;
                        &lt;add name="Foo" value="Bar" /&gt;
                    &lt;/settings&gt;
                &lt;/processor&gt;
                &lt;settings&gt;
                    &lt;add name="Path" value="C:\" /&gt;
                &lt;/settings&gt;
            &lt;/monitor&gt;
        &lt;/monitors&gt;
    &lt;/siphon&gt;
&lt;/configuration&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://chrislaco.com/articles/siphon-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Always Set Application Name In SqlClient Connection Strings</title>
		<link>http://chrislaco.com/manifesto/always-set-application-name-in-sqlclient-connection-strings/</link>
		<comments>http://chrislaco.com/manifesto/always-set-application-name-in-sqlclient-connection-strings/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 04:05:21 +0000</pubDate>
		<dc:creator>claco</dc:creator>
				<category><![CDATA[Manifesto]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[application name]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[connection string]]></category>

		<guid isPermaLink="false">http://chrislaco.com/?p=79</guid>
		<description><![CDATA[If you&#8217;re using connection strings on the web, set Application Name to the domain name. If you&#8217;re using connection strings with an executable, set Application Name to the executable name. If you have to use SQL Profiler to diagnose performance &#8230; <a href="http://chrislaco.com/manifesto/always-set-application-name-in-sqlclient-connection-strings/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re using connection strings on the web, set Application Name to the domain name. If you&#8217;re using connection strings with an executable, set Application Name to the executable name. If you have to use SQL Profiler to diagnose performance issues, it will be easier to filter out a specific application or web site.</p>
<pre class="brush:xml">&lt;connectionStrings&gt;
  &lt;add name="LocalSqlServer" connectionString="... Application Name=mywebsite.com;" /&gt;
  &lt;add name="LocalSqlServer" connectionString="... Application Name=myapp.exe" /&gt;
&lt;/connectionStrings&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://chrislaco.com/manifesto/always-set-application-name-in-sqlclient-connection-strings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ConfigurationElementCollection Gotcha</title>
		<link>http://chrislaco.com/software/configurationelementcollection-gotcha/</link>
		<comments>http://chrislaco.com/software/configurationelementcollection-gotcha/#comments</comments>
		<pubDate>Sun, 02 Nov 2008 04:03:34 +0000</pubDate>
		<dc:creator>claco</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[custom]]></category>

		<guid isPermaLink="false">http://chrislaco.com/?p=58</guid>
		<description><![CDATA[Here&#8217;s a fun way to waste 2 hours of your life. I was writing a custom config section, and trying to figure out why this wasn&#8217;t throwing a duplicate key error: &#60;monitors&#62; &#60;monitor name="File" /&#62; &#60;monitor name="File" /&#62; &#60;/monitors&#62; After &#8230; <a href="http://chrislaco.com/software/configurationelementcollection-gotcha/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a fun way to waste 2 hours of your life. I was writing a custom config section, and trying to figure out why this wasn&#8217;t throwing a duplicate key error:<br />
<span id="more-58"></span></p>
<pre class="brush:xml">&lt;monitors&gt;
  &lt;monitor name="File" /&gt;
  &lt;monitor name="File" /&gt;
&lt;/monitors&gt;</pre>
<p>After surfing Google endlessly, I finally found this on MSDN:</p>
<blockquote><p>Note that elements with identical keys and values are not considered duplicates, and are accepted silently. Only elements with identical keys but different values are considered duplicates.</p></blockquote>
<p>That was fun. :-/</p>
]]></content:encoded>
			<wfw:commentRss>http://chrislaco.com/software/configurationelementcollection-gotcha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
