<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>development</title>
        <link>http://blog.kellybrownsberger.com/category/8.aspx</link>
        <description>development</description>
        <language>en-US</language>
        <copyright>kellyb</copyright>
        <generator>Subtext Version 2.1.0.5</generator>
        <item>
            <title>Using XPath to select nodes with a missing attribute</title>
            <link>http://blog.kellybrownsberger.com/archive/2010/01/14/73.aspx</link>
            <description>&lt;p&gt;The only thing worse than my XPath skills are my RegEx skills.  I don’t use XPath all that much these days, but today I needed to.  It took me a while to find a code sample that does this.  After a playing a bit with SnippetCompiler, I found the solution:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;pre class="csharpcode"&gt;StringBuilder builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();
builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;foo&amp;gt;"&lt;/span&gt;);
builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;bar baz=\"a\"&amp;gt;1&amp;lt;/bar&amp;gt;"&lt;/span&gt;);
builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;bar&amp;gt;2&amp;lt;/bar&amp;gt;"&lt;/span&gt;);
builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;bar baz=\"b\"&amp;gt;3&amp;lt;/bar&amp;gt;"&lt;/span&gt;);
builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;bar&amp;gt;4&amp;lt;/bar&amp;gt;"&lt;/span&gt;);
builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;bar baz=\"c\"&amp;gt;5&amp;lt;/bar&amp;gt;"&lt;/span&gt;);
builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;/foo&amp;gt;"&lt;/span&gt;);

XmlDocument doc = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlDocument();
doc.LoadXml(builder.ToString());

XmlNodeList nodes = doc.SelectNodes(&lt;span class="str"&gt;"//foo/bar[not(@baz)]"&lt;/span&gt;);

&lt;span class="kwrd"&gt;if&lt;/span&gt; ( nodes == &lt;span class="kwrd"&gt;null&lt;/span&gt; )
{
    WL(&lt;span class="str"&gt;"nodes was null"&lt;/span&gt;);
}
&lt;span class="kwrd"&gt;else&lt;/span&gt;
{
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; ( XmlNode node &lt;span class="kwrd"&gt;in&lt;/span&gt; nodes )
    {
        WL(&lt;span class="str"&gt;"Node: "&lt;/span&gt; + node.InnerText);
    }
}&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div class="csharpcode"&gt; &lt;/div&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;&lt;a href="http://blog.kellybrownsberger.com/____Uploads____/UsingXPathtoselectnodeswithamissingattri_11A85/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.kellybrownsberger.com/____Uploads____/UsingXPathtoselectnodeswithamissingattri_11A85/image_thumb.png" width="216" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.kellybrownsberger.com/____Uploads____/UsingXPathtoselectnodeswithamissingattri_11A85/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.kellybrownsberger.com/____Uploads____/UsingXPathtoselectnodeswithamissingattri_11A85/image_thumb_3.png" width="244" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/73.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2010/01/14/73.aspx</guid>
            <pubDate>Fri, 15 Jan 2010 01:05:58 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/73.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2010/01/14/73.aspx#feedback</comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/73.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Hand-Shaping the XML Schema of your data contract using IXmlSerializable</title>
            <link>http://blog.kellybrownsberger.com/archive/2009/04/10/47.aspx</link>
            <description>&lt;p&gt; &lt;/p&gt; &lt;p&gt;I’ve been getting into some pretty advanced scenarios with WCF where we need to precisely shape the XML on the wire and the schema’s that are produced by svcutil.exe.  Trust me, the moment you start using WCF for exposing services to Java clients, those Java clients are really going to care how the XML looks.  WCF makes .NET-to-.NET very easy, and .NET-to-Java doable, but I wouldn’t call it easy.  For vanilla scenarios  (simple contracts with simple types and basic complex types), it’s pretty easy.  The hooks exposed by WCF for shaping the XML are pretty poor in my opinion.&lt;/p&gt; &lt;p&gt;IXmlSerializable is your friend when it comes to shaping the xml on the wire.  It will work with the Data Contract Serializer in WCF, but if you google around trying to find info on people using IXmlSerializable, you’ll quickly get confused.  I wanted to hand-roll how my entity serializes, and this interface is very straightforward for that.  For shaping the schema, it’s not straight forward in the slightest.  Below are several lessons I learned over a number of days while working with IXmlSerialiable:&lt;/p&gt; &lt;ol&gt; &lt;h4 /&gt;&lt;/ol&gt; &lt;h3&gt;GetSchema is not what you use to shape the schema!&lt;/h3&gt; &lt;p&gt;I don’t know what this method is for, but it’s not what it sounds like.  Everything you’ll find on google is people returning null.  If you programmatically construct an XmlSchema instance, and return it from GetSchema(), it won’t be used.  As far as I can tell, the Data Contract Serializer never calls this method.  Instead, you have to decorate your class with the XmlSchemaProvider attribute and specify the static method that should be called for shaping the schema.  This method should accept an argument of type XmlSchemaSet and in that method is where you should construct your schema, and add it to the XmlSchemaSet.  It appears the method you implement must return either an instance of XmlQualifiedName or any derivative of XmlSchemaObject (i.e. XmlSchemaComplexType or XmlSchemaSimpleType).  Here’s an example:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    [XmlSchemaProvider(&lt;span class="str"&gt;"ConstructSchema"&lt;/span&gt;)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Product : IXmlSerializable
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; _deserializing;
        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; _data;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Data
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _data; }
            set { _data = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; XmlQualifiedName ConstructSchema(XmlSchemaSet schemaSet)
        {
            &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; theNamespace = &lt;span class="str"&gt;"http://webservices.kellybrownsberger.com/1.0"&lt;/span&gt;;

            XmlSchema schema = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlSchema
            {
                TargetNamespace = theNamespace,
                ElementFormDefault = XmlSchemaForm.Qualified
            };

            schemaSet.Add(schema);

            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlQualifiedName(&lt;span class="str"&gt;"Product"&lt;/span&gt;, theNamespace);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; XmlSchema GetSchema()
        {
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; NotImplementedException(&lt;span class="str"&gt;"Not implemented - the XMmlSchemaProvider attribute specifies calling the static GetSchema method instead"&lt;/span&gt;);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ReadXml(XmlReader reader)
        {
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WriteXml(XmlWriter writer)
        {
        }
    }&lt;/pre&gt;&lt;pre class="csharpcode"&gt; &lt;/pre&gt;
&lt;h3&gt;Shaping Schema using a read-in xml string&lt;/h3&gt;
&lt;p&gt;This is handy for two things in my mind – readability and code-gen.  People tend to like looking at a schema in an xml representation.  It’s more error prone, and not refactor-tool-friendly, but it’s more readable to the masses I think.  Secondly, I like to code-gen my contracts in batch (&lt;a href="http://msdn.microsoft.com/en-us/library/bb126445.aspx" target="_blank"&gt;using T4&lt;/a&gt;).  Typically, I’ll define some XML grammar (DSL if you will), that describes my entities.  I can then gen them all and make sure all of the correct attributes are applied.  This might seem silly, but in large systems with interoperability being a top-priority, keeping all of your DataContract and DataMember attributes correct (one forgotten or botched namespace declaration can hose our consumers) is a bit daunting.  When you get into the more complex things like contract versioning, and types implementing IXmlSerialable, it’s very daunting.  Being able to code-gen this stuff has a lot of advantages.  Reading in XML Schema as text is code-gen friendly as it can easily be captured as part of the DSL/grammar I mentioned, and the necessary code can be generating quickly and easilyand because your generating it, it’s less error prone.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; XmlQualifiedName ConstructSchema(XmlSchemaSet schemaSet)
        {
            &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; theNamespace = &lt;span class="str"&gt;"http://webservices.kellybrownsberger.com/1.0"&lt;/span&gt;;

            StringBuilder builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();
            builder.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"&amp;lt;xs:schema xmlns:tns=\"{0}\" elementFormDefault=\"qualified\" targetNamespace=\"{0}\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"&amp;gt;"&lt;/span&gt;, theNamespace));
            builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;xs:complexType name=\"Product\"&amp;gt;"&lt;/span&gt;);
            builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;xs:sequence minOccurs=\"1\" maxOccurs=\"1\"&amp;gt;"&lt;/span&gt;);
            builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;xs:any /&amp;gt;"&lt;/span&gt;);
            builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;/xs:sequence&amp;gt;"&lt;/span&gt;);
            builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;/xs:complexType&amp;gt;"&lt;/span&gt;);
            builder.AppendLine(&lt;span class="str"&gt;"&amp;lt;/xs:schema&amp;gt;"&lt;/span&gt;);

            XmlSchema schema = XmlSchema.Read(&lt;span class="kwrd"&gt;new&lt;/span&gt; StringReader(builder.ToString()), &lt;span class="kwrd"&gt;null&lt;/span&gt;);

            schemaSet.Add(schema);

            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlQualifiedName(&lt;span class="str"&gt;"Product"&lt;/span&gt;, theNamespace);
        }
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;&lt;style type="text/css"&gt;&lt;![CDATA[csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
]]&gt;&lt;/style&gt;

&lt;h3&gt;Shaping Schema programmatically&lt;/h3&gt;
&lt;p&gt;It took me longer than I care to admit to figure out how to do this correctly (it took me forever to figure out that I needed to sequence to the XmlSchemaComplexType’s Particle property).  Here’s an example:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; XmlSchemaComplexType ConstructSchema(XmlSchemaSet schemaSet)
        {
            &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; theNamespace = &lt;span class="str"&gt;"http://webservices.kellybrownsberger.com/1.0"&lt;/span&gt;;

            XmlSchema schema = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlSchema
            {
                TargetNamespace = theNamespace,
                ElementFormDefault = XmlSchemaForm.Qualified
            };

            XmlSchemaComplexType type = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlSchemaComplexType { Name = &lt;span class="str"&gt;"Product"&lt;/span&gt; };
            schema.Items.Add(type);
            
            XmlSchemaSequence sequence = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlSchemaSequence {MinOccurs = 1, MaxOccurs = 1};
            sequence.Items.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; XmlSchemaAny());
            type.Particle = sequence;

            schemaSet.Add(schema);

            &lt;span class="kwrd"&gt;return&lt;/span&gt; type;
        }
&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
]]&gt;&lt;/style&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/47.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2009/04/10/47.aspx</guid>
            <pubDate>Fri, 10 Apr 2009 15:14:55 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/47.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2009/04/10/47.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/47.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Testable WCF ServiceHost</title>
            <link>http://blog.kellybrownsberger.com/archive/2009/03/17/43.aspx</link>
            <description>&lt;p&gt;I’m finally getting a chance to sink my teeth into Windows Communication Foundation (WCF).  I’m finding quite a few gaps on the interoperability side of things, and I think it’s overly complex in it’s configuration schemes and extensibility points, but it’s light years beyond what we had previously in ASMX.  From what I can tell, the WCF adoption was just much slower than everyone anticipated.  I’m not sure why that is – perhaps it’s the vastness of it that’s intimidated people.  Perhaps it was the quality of the the .NET version 2.0 release that resulted in a slow adoption of all of version 3.0+.  For whatever reason, this seems to have caused a number of rough edges in the product to sit dormant for a couple of years now.  &lt;/p&gt;  &lt;p&gt;At any rate, WCF is now part of my every day day-job, and I’m trying to find ways to make it more testable.  We have a suite of what I’d call System Tests.  Unit Tests by my definition, test at the object (or component) boundary while System Tests test at a collection of objects (or components).  Our system is highly configurable, and behaviors vary dramatically from one configuration to the next.  We’d like to have the ability to have a repeatable suite of automated test that can test all of our out-of-the-box configurations.&lt;/p&gt;  &lt;p&gt;To date we’ve been executing our tests by .bat file (shelling to MbUnit.Cons.exe) after copying copies of our config files to our hosting IIS project.  This is less than awesome for a few reasons:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;It’s Slow and Flakey&lt;/strong&gt; – Running test out of process (which is what IIS is) is always slower than in-process.  Keep our test suite blazing fast is highly desirable.  Also, when you’re doing this kind of thing, it’s not uncommon to need to restart IIS between tests (IIS caching certain types of config data, etc.), which can really slow down the party.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;It’s Heavy and Hard to Setup&lt;/strong&gt; – IIS is required to be installed on any machine that wants to run the tests.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;It’s Awkward&lt;/strong&gt; – We must have .bat files that copy around our Web.config files that contain our test configuration before executing our tests.  The natural experience of running our tests directly from the IDE is lost.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Luckily, WCF is highly extensible and customizable in it’s hosting infrastructure.  In the System.ServiceModel of the .NET Framework, they expose everything you need to easily create your own host for your WCF services.  We’ve all seen the MSN samples that hosts your hello-world service with a Console app.  To make our automated tests more awesome, I created a TestableServer service host implementation.&lt;/p&gt;  &lt;h3&gt;The Service&lt;/h3&gt;  &lt;p&gt;Lets say we have a service like this…&lt;/p&gt;  &lt;pre class="csharpcode"&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// Here's my service implementation&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SomeService : ISomeService
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime GetCurrentDate()
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; DateTime.Now.Date;
        }
    }

    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// Here's my service contract for my implementation&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    [ServiceContract]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ISomeService
    {
        [OperationContract]
        DateTime GetCurrentDate();
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;The Test&lt;/h3&gt;

&lt;p&gt;With the TestableServer, I can write a tidy little test like so…&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    [TestFixture]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SomeServiceFixture
    {
        [Test]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Can_We_Invoke_GetCurrentDate()
        {
            &lt;span class="kwrd"&gt;using&lt;/span&gt; (TestableServer&amp;lt;SomeService, ISomeService&amp;gt; server = &lt;span class="kwrd"&gt;new&lt;/span&gt; TestableServer&amp;lt;SomeService, ISomeService&amp;gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; BasicHttpBinding()))
            {
                ISomeService proxy = server.CreateProxy();

                DateTime actual = proxy.GetCurrentDate();

                Assert.AreEqual(DateTime.Now.Date, actual.Date);
            }
        }
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;By passing a few generics, it has all the information it needs to host my service in-memory and I can execute tests against it directly.  Notice in the TestableServer constructor, I’m passing in the binding I’d like to use.  Here I can specify netTcpBinding, msmqBinding, or any of they other support bindings.  Here I’m using vanilla HTTP.&lt;/p&gt;

&lt;h3&gt;The Code&lt;/h3&gt;

&lt;p&gt;There’s not much to it at all, but here’s the code behind TestableServer…&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TestableServer&amp;lt;TServiceImp, TServiceInt&amp;gt; : IDisposable &lt;span class="kwrd"&gt;where&lt;/span&gt; TServiceImp : &lt;span class="kwrd"&gt;class&lt;/span&gt;
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; ServiceHost _host;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; Type _serviceImplType = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(TServiceImp);
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; Type _serviceIntType = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(TServiceInt);
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _url;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; Binding _binding;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; ChannelFactory&amp;lt;TServiceInt&amp;gt; _factory;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; TServiceInt _channel;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; TestableServer() : &lt;span class="kwrd"&gt;this&lt;/span&gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; NetTcpBinding()) { }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; TestableServer(Binding binding)
        {
            _host = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceHost(_serviceImplType);
            _binding = binding;

            _url = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"{0}://localhost/{1}"&lt;/span&gt;, _binding.Scheme, Guid.NewGuid());
            _host.AddServiceEndpoint(_serviceIntType, _binding,  _url);

            &lt;span class="kwrd"&gt;try&lt;/span&gt;
            {
                _host.Open();
                
            }
            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (TimeoutException timeoutEx)
            {
                Console.WriteLine(&lt;span class="str"&gt;"Failed to close the service host - Exception: "&lt;/span&gt; + timeoutEx.Message);
                &lt;span class="kwrd"&gt;throw&lt;/span&gt;;
            }
            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (CommunicationException communicationEx)
            {
                Console.WriteLine(&lt;span class="str"&gt;"Failed to close the service host - Exception: "&lt;/span&gt; + communicationEx.Message);
                &lt;span class="kwrd"&gt;throw&lt;/span&gt;;
            }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; TServiceInt CreateProxy()
        {
            _factory = &lt;span class="kwrd"&gt;new&lt;/span&gt; ChannelFactory&amp;lt;TServiceInt&amp;gt;(_binding);
            _channel = _factory.CreateChannel(&lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(_url));
            
            &lt;span class="kwrd"&gt;return&lt;/span&gt; _channel;
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Dispose()
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; ( _factory != &lt;span class="kwrd"&gt;null&lt;/span&gt; )
            {
                _factory.Close();
                _factory = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
            }

            TearDown();
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TearDown()
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_host != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                &lt;span class="kwrd"&gt;try&lt;/span&gt;
                {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; ( _host.State == CommunicationState.Opened || _host.State ==CommunicationState.Opening)
                    {
                        _host.Close();
                    }
                }
                &lt;span class="kwrd"&gt;catch&lt;/span&gt; (TimeoutException timeoutEx)
                {
                    Console.WriteLine(&lt;span class="str"&gt;"Failed to close the service host - Exception: "&lt;/span&gt; + timeoutEx.Message);
                }
                &lt;span class="kwrd"&gt;catch&lt;/span&gt; (CommunicationException communicationEx)
                {
                    Console.WriteLine(&lt;span class="str"&gt;"Failed to close the service host - Exception: "&lt;/span&gt; + communicationEx.Message);
                }
                &lt;span class="kwrd"&gt;finally&lt;/span&gt;
                {
                    _host = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
                }
            }
        }
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;h3&gt;The Ultimate Goal&lt;/h3&gt;

&lt;p&gt;So, I haven’t actually achieved my ultimate goal yet, which is to be able to programmatically configure the server/service for each of our supported configurations and execute our test suites against those configurations.  That’s what I’m going to work on next, and without IIS between my test fixture and my service implementation, achieving that goal should be relatively simple.&lt;/p&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/43.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2009/03/17/43.aspx</guid>
            <pubDate>Wed, 18 Mar 2009 03:50:00 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/43.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2009/03/17/43.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/43.aspx</wfw:commentRss>
        </item>
        <item>
            <title>2009 &amp;ndash; Base Personal Image</title>
            <link>http://blog.kellybrownsberger.com/archive/2009/01/12/37.aspx</link>
            <description>&lt;p&gt;Some time ago I wrote a post called &lt;a href="http://blog.kellybrownsberger.com/archive/0001/01/01/16.aspx" target="_blank"&gt;Base Personal Image&lt;/a&gt;.  I wanted to write an update to that, but decided it would be nice to have it in it’s original date for historical purposes.  So, I’m writing a new post and stamping it with the year.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Here’s the topology of my setup&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.kellybrownsberger.com/____Uploads____/2009BasePersonalImage_128C1/home_technology_topology.jpg"&gt;&lt;img title="home_technology_topology" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="484" alt="home_technology_topology" src="http://blog.kellybrownsberger.com/____Uploads____/2009BasePersonalImage_128C1/home_technology_topology_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;The staple of my setup are &lt;a href="http://www.mesh.com" target="_blank"&gt;Windows Live Mesh&lt;/a&gt; (this replaced Folder Share for me – now called Windows Live Synch).  This is what ties everything together for me.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Core&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Windows Vista SP1 with IIS &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/netframework/aa569263.aspx" target="_blank"&gt;.NET Framework 1.1, 2.0, 3.5 &lt;/a&gt;      &lt;/li&gt;&lt;li /&gt;     &lt;a href="http://free.avg.com/" target="_blank"&gt;AVG Free Anti-Virus&lt;/a&gt;     &lt;li&gt;&lt;a href="http://www.7-zip.org/" target="_blank"&gt;7-Zip&lt;/a&gt; – the fastest there is&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.mozilla.org/firefox" target="_blank"&gt;FireFox 3.0&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.foxitsoftware.com/pdf/rd_intro.php" target="_blank"&gt;Foxit Reader&lt;/a&gt; - stay away from Acrobat... it's a dog &lt;/li&gt;    &lt;li&gt;&lt;a href="www.microsoft.com/windows/products/winfamily/desktopsearch/default.mspx" target="_blank"&gt;Windows Search 4.0&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.google.com/talk/" target="_blank"&gt;Google Talk&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://office.microsoft.com/en-us/suites/FX101674121033.aspx" target="_blank"&gt;Office 2007 Ultimate&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=4d951911-3e7e-4ae6-b059-a2e79ed87041&amp;amp;displaylang=en&amp;amp;Hash=%2blgYFIbG6gvxjnf%2bSxEIq6SB3SLFfRa4Ur6fDRbau5yjLr93jvTwiK%2fLC7YXtSdJYwN5%2bRRzKsPb4C6B9zh%2bzA%3d%3d" target="_blank"&gt;Save as PDF add-in for Office&lt;/a&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="http://messenger.live.com" target="_blank"&gt;Windows Live Messenger&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.codesector.com/teracopy.php"&gt;TeraCopy&lt;/a&gt; – RoboCopy-like features from the Windows Shell &lt;/li&gt;    &lt;li&gt;Windows Home Server Console – available for download from your Windows Home Server&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Power Using&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.geekdojo.net/brian/articles/Cropper.aspx" target="_blank"&gt;Cropper&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.getpaint.net/download.html" target="_blank"&gt;Paint.NET&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.launchy.net/" target="_blank"&gt;Launchy&lt;/a&gt; - this replaced SlickRun for me when Launchy released a plugin model along with a "Runner" plugin (which does just about everything SlickRun does). &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&amp;amp;displaylang=en" target="_blank"&gt;Windows 2003 Resource Kit Tools&lt;/a&gt; (Robocopy) &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.textpad.com" target="_blank"&gt;TextPad&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.flos-freeware.ch/notepad2.html" target="_blank"&gt;Notepad2&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://technet.microsoft.com/en-us/sysinternals/0e18b180-9b7a-4c49-8120-c47c5a693683.aspx" target="_blank"&gt;Sysinternals SuiteDisk&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.download.com/ClipPath/3000-2094_4-10050927.html" target="_blank"&gt;ClipPath&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://free.grisoft.com/doc/avg-anti-virus-free/lng/us/tpl/v5" target="_blank"&gt;Daemon Tools&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.newsgator.com/NGOLProduct.aspx?ProdID=FeedDemon" target="_blank"&gt;Password Agent&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://wordweb.info/free/" target="_blank"&gt;WordWeb&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://lifehacker.com/software/texter/lifehacker-code-texter-windows-238306.php" target="_blank"&gt;Texter&lt;/a&gt; - I need to post on this one.  This is a niche utility that I don't use all that often, but very nice in certain common situations.  It has its quirks though. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Backup and Recovery&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.mozy.com/" target="_blank"&gt;Mozy&lt;/a&gt; – I use to have Mozy running on all of my machines, but since investing in a Windows Home Server – I only use Mozy at my office&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.keepvault.com/" target="_blank"&gt;Keep Vault&lt;/a&gt; – I use this to backup my entire Windows Home Server&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.mesh.com" target="_blank"&gt;Windows Live Mesh&lt;/a&gt; – Mesh runs on all of my machines.  I use it to synch a few other things, but I primarily use it to keep my Password Agent password file in synch across all of my machines.  This also backs up all of my files to the cloud and makes them web accessible.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.moonsoftware.com/bmagic.asp" target="_blank"&gt;Backup Magic&lt;/a&gt; – For simple Backup operations&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Media and Entertainment&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://windowslivewriter.spaces.live.com/" target="_blank"&gt;Windows Live Writer&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.yessoftware.com/products/product.php?product_id=19" target="_blank"&gt;DemoCharge&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/windows/windowsmedia/player/11/default.aspx" target="_blank"&gt;Windows Media Player 11&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://picasa.google.com/" target="_blank"&gt;Picasa&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/teamsystem/aa718822.aspx" target="_blank"&gt;Visual Studio 2005 Team Suite&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vsts2008/default.aspx" target="_blank"&gt;Visual Studio 2008 Team Suite&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.jetbrains.com/resharper/" target="_blank"&gt;ReSharper&lt;/a&gt; – Invaluable refactoring tool for Visual Studio&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.mbunit.com/"&gt;MbUnit&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.testdriven.net" target="_blank"&gt;TestDriven.NET&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.codesmithtools.com" target="_blank"&gt;CodeSmith&lt;/a&gt; - I barely use this one anymore, but it still makes the list &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/sqlserver/2008/en/us/app-dev.aspx" target="_blank"&gt;SQL Server 2008 Developer Edition&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/" target="_blank"&gt;.NET Reflector&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.sliver.com/dotnet/snippetcompiler/" target="_blank"&gt;SnippetCompiler&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://tortoisesvn.tigris.org/" target="_blank"&gt;TortoiseSVN&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.visualsvn.com/" target="_blank"&gt;VisualSVN&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.memprofiler.com" target="_blank"&gt;.NET Memory Profiler&lt;/a&gt; – It does everything you could ever want in the world of .NET memory profiling, for a small price tag… and the documentation kicks the shit out of Ants and dotTrace&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Family Tech Support&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When my family calls with a PC problem, I use &lt;a href="http://windowslivewriter.spaces.live.com/" target="_blank"&gt;CrossLoop&lt;/a&gt; (free and usually works) or &lt;a href="http://www.copilot.com/" target="_blank"&gt;Copilot&lt;/a&gt; (for the rare occasions when CrossLoop won’t connect) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Universal Drivers, Codecs, etc.&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.techsmith.com/download/codecs.asp" target="_blank"&gt;TechSmith Screen Capture Codec&lt;/a&gt; - commonly used on web screencasts &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/37.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2009/01/12/37.aspx</guid>
            <pubDate>Tue, 13 Jan 2009 02:07:07 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/37.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2009/01/12/37.aspx#feedback</comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/37.aspx</wfw:commentRss>
        </item>
        <item>
            <title>DOS and VBS Syntax Reminders</title>
            <link>http://blog.kellybrownsberger.com/archive/2008/08/22/5.aspx</link>
            <description>&lt;p&gt;From time to time I have to break out skills from my past.  I needed to solve a few problems today that required a VBS script and a couple of batch scripts.  It took me longer than I care to admit to remember how to do this.&lt;/p&gt;
&lt;p&gt;So, this post is a reminder for my future self.&lt;/p&gt;
&lt;p&gt;Here's how to set a local variable in DOS and use them, as well as how to use a system environment variable (WinDir):&lt;/p&gt;
&lt;div&gt;
&lt;div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   1:&lt;/span&gt; SET INTERNAL_ROOT_PATH=D:\foo\trunk&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   2:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   3:&lt;/span&gt; svn.exe update %INTERNAL_ROOT_PATH%&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   4:&lt;/span&gt; %WinDir%\Microsoft.NET\Framework\v2.0.50727\msbuild.exe %INTERNAL_ROOT_PATH%\Internal.sln /Property:Config=Release&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here is how to load an XML file into XML DOM and parse it using MSXML2 and VBScript.  This is also an example of how to Echo messages to the shell and process arguments&lt;/p&gt;
&lt;div&gt;
&lt;div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   1:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   2:&lt;/span&gt;     path = WScript.Arguments(0)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   3:&lt;/span&gt;     root = WScript.Arguments(1)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   4:&lt;/span&gt;     &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   5:&lt;/span&gt;     gacpath = &lt;span style="color: rgb(0, 96, 128);"&gt;"D:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe"&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   6:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   7:&lt;/span&gt;     If WScript.Arguments.Count = 3 Then&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   8:&lt;/span&gt;         gacpath = WScript.Arguments(2)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   9:&lt;/span&gt;     End If&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  10:&lt;/span&gt;     &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  11:&lt;/span&gt;     WScript.Echo WScript.Arguments.Count&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  12:&lt;/span&gt;     WScript.Echo &lt;span style="color: rgb(0, 96, 128);"&gt;"Parsing LibraryManifest: "&lt;/span&gt; &amp;amp; path&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  13:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  14:&lt;/span&gt;     Set xml = CreateObject(&lt;span style="color: rgb(0, 96, 128);"&gt;"MSXML2.DOMDocument"&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  15:&lt;/span&gt;     With xml&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  16:&lt;/span&gt;         .async = False &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  17:&lt;/span&gt;         .validateOnParse = False &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  18:&lt;/span&gt;         .preserveWhiteSpace = True&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  19:&lt;/span&gt;         .resolveExternals = False &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  20:&lt;/span&gt;     End With&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  21:&lt;/span&gt;     result = xml.load(path)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  22:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  23:&lt;/span&gt;     Set moduleNodes = xml.selectNodes(&lt;span style="color: rgb(0, 96, 128);"&gt;"//LibraryManifest/Module"&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  24:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  25:&lt;/span&gt;     If Not moduleNodes Is Nothing Then&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  26:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  27:&lt;/span&gt;         For Each moduleNode &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; moduleNodes&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  28:&lt;/span&gt;             &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  29:&lt;/span&gt;             Set assemblyNodes = moduleNode.selectNodes(&lt;span style="color: rgb(0, 96, 128);"&gt;"Assembly"&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  30:&lt;/span&gt;             &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  31:&lt;/span&gt;             For Each assemblyNode &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; assemblyNodes&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  32:&lt;/span&gt;             &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  33:&lt;/span&gt;                 For Each attribute &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; assemblyNode.Attributes&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  34:&lt;/span&gt;                     &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  35:&lt;/span&gt;                     If attribute.Name = &lt;span style="color: rgb(0, 96, 128);"&gt;"Name"&lt;/span&gt; Then&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  36:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  37:&lt;/span&gt;                         file = root &amp;amp; &lt;span style="color: rgb(0, 96, 128);"&gt;"\" &amp;amp; attribute.Text&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  38:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  39:&lt;/span&gt;                         'WScript.Echo "file: &lt;span style="color: rgb(0, 96, 128);"&gt;" &amp;amp; file&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  40:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  41:&lt;/span&gt;                         Set shell = CreateObject("WScript.Shell&lt;span style="color: rgb(0, 96, 128);"&gt;")&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  42:&lt;/span&gt;                         gacutil = gacpath &amp;amp; " -uf &lt;span style="color: rgb(0, 96, 128);"&gt;" &amp;amp; attribute.Text&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  43:&lt;/span&gt;                         Set out = shell.Exec(gacutil)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  44:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  45:&lt;/span&gt;                         Do While Not out.StdOut.AtEndOfStream&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  46:&lt;/span&gt;                             WScript.Echo out.StdOut.ReadLine()&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  47:&lt;/span&gt;                         Loop    &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  48:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  49:&lt;/span&gt;                         Set shell = CreateObject("WScript.Shell&lt;span style="color: rgb(0, 96, 128);"&gt;")&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  50:&lt;/span&gt;                         gacutil = gacpath &amp;amp; " -&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; " &amp;amp; file&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  51:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  52:&lt;/span&gt;                         Set out = shell.Exec(gacutil)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  53:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  54:&lt;/span&gt;                         Do While Not out.StdOut.AtEndOfStream&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  55:&lt;/span&gt;                             WScript.Echo out.StdOut.ReadLine()&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  56:&lt;/span&gt;                         Loop    &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  57:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  58:&lt;/span&gt;                         Set shell = Nothing&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  59:&lt;/span&gt;                         Set out = Nothing&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  60:&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  61:&lt;/span&gt;                     End If&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  62:&lt;/span&gt;                 Next&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  63:&lt;/span&gt;             Next&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  64:&lt;/span&gt;         Next&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  65:&lt;/span&gt;     End If&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  66:&lt;/span&gt;     &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/5.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2008/08/22/5.aspx</guid>
            <pubDate>Fri, 22 Aug 2008 04:00:00 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/5.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2008/08/22/5.aspx#feedback</comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/5.aspx</wfw:commentRss>
        </item>
        <item>
            <title>The Entity Framework team should talk to the MVC team</title>
            <link>http://blog.kellybrownsberger.com/archive/2008/05/21/6.aspx</link>
            <description>&lt;p&gt;Two product efforts at Microsoft have spun up this year and both are new implementations of very old ideas:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx"&gt;ASP.NET MVC Framework&lt;/a&gt; - Microsoft's upcoming implementation of a Model View Controller architecture for their web application platform.  MVC has been around for a long time on other development platforms, but only recently has there been a push in the .NET community demanding for this.      &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a target="_blank" href="http://blogs.msdn.com/dsimmons/archive/2008/05/17/why-use-the-entity-framework.aspx"&gt;ADO.NET Entity Framework&lt;/a&gt; - Microsoft's next rev of data access technology (ADO.NET) contains a lot of new ways to work with data.  EF is their implementation of an Object-Relational Mapping framework.  Again, OR Mapping has been around for a very long time on other development platforms such as Java, but only recently has there been a push in the .NET community asking for this.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My personal opinion is the recent increase in the popularity of Agile development methods has had a large part in driving out these products from Microsoft.  Agile development tends to accentuates everything in a development ecosystem - the good and the bad.  Agile teams using the .NET platform have been feeling a lot of pain in certain areas - namely, data access and web app development.  Writing automated-test-friendly code using these parts of the framework has been a nightmare for me personally, and I know there's scores of people that feel the same way.&lt;/p&gt;
&lt;p&gt;To be fair, there's a large part of the .NET community that just doesn't care about any of this.  By and large, they don't care about Agile and they don't care about automated test friendliness and they think the current implementations of ASP.NET and ADO.NET are just fine.  I'm not going to argue with any of that because those people are in the best position to know what's best for them.  However, there are people out there that loudly crying for change, and I'm one of them (though most of my crying is done in my own head).&lt;/p&gt;
&lt;p&gt;What's really interesting I think is to watch how the MVC team has went about this charge in comparison to the EF team.  I pay a lot more attention to the MVC stuff just because I've been a long time reader of &lt;a target="_blank" href="http://www.hanselman.com/blog/ScottGuMVCPresentationAndScottHaScreencastFromALTNETConference.aspx"&gt;Scott Hanselman&lt;/a&gt;, &lt;a target="_blank" href="http://haacked.com/"&gt;Phil Haack&lt;/a&gt;, and &lt;a target="_blank" href="http://blog.wekeroad.com/"&gt;Rob Conery&lt;/a&gt; (the 3 main guys Microsoft hired to make lead the MVC effort).  If you read through these guy's blog's and the content they're producing to support this product, their "this is for a certain set of people with a certain set of concerns that doesn't apply to everyone and we want this product to delight those people" attitude is obvious, which is very refreshing.  &lt;a target="_blank" href="http://www.google.com/reader/view/?tab=my#stream/feed%2Fhttp%3A%2F%2Ffeeds.feedburner.com%2FScottHanselman"&gt;Scott posted some very cool video's of his talks on MVC at Mix this year&lt;/a&gt;.  This refreshing attitude shines thoroughly repeatedly in these talks.&lt;/p&gt;
&lt;p&gt;Dan Simmons from the Entity Framework team &lt;a target="_blank" href="http://blogs.msdn.com/dsimmons/archive/2008/05/17/why-use-the-entity-framework.aspx"&gt;posted a break down&lt;/a&gt; of the data access technologies in ADO.NET and compares and contrasts them for different types of jobs.  As expected, the Agile/TDD zealots are pounding on him (i.e. &lt;a target="_blank" href="http://www.google.com/reader/view/?tab=my#stream/feed%2Fhttp%3A%2F%2Fcodebetter.com%2Fblogs%2Fjeremy.miller%2Frss.aspx"&gt;Jeremy Miller&lt;/a&gt; and the &lt;a target="_blank" href="http://codebetter.com/Default.aspx"&gt;CodeBetter crew&lt;/a&gt;).  The zealots don't like the EF team's model and they take every opportunity to remind them of that.  The EF team seems view these folks and their viewpoints as a small subset of the community.  They seem to be applying the 80/20 rule, and they seem to think that if only 20% of the community is pissed, then that's pretty good.&lt;/p&gt;
&lt;p&gt;What I think Dan is missing here, unlike the MVC team, this 20% of people that are displeased with their model, is the majority of people that care about this stuff.  The other 80% are the people that don't care about Agile and don't care about automated-test-friendliness.  They are the people that are more than happy cranking out dataset based app after dataset based app.  I would argue, they are the definitely NOT the people that are creating conceptual data models for reuse across their domain (the EF's big selling point).  I think the EF team needs to watch the MVC team and start listening to the zealots.  &lt;u&gt;Those zealots are your customer&lt;/u&gt;.&lt;/p&gt;
&lt;p&gt;My prediction:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;ASP.NET MVC Framework:  &lt;font size="4"&gt;&lt;font color="#008000"&gt;&lt;strong&gt;Huge Success&lt;/strong&gt;          &lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;
    &lt;li&gt;ADO.NET Entity Framework:  &lt;strong&gt;&lt;font size="4" color="#ff0000"&gt;Huge Failure&lt;/font&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I would love to be wrong about #2.  #1 seems to already be in the bag :)&lt;/p&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/6.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2008/05/21/6.aspx</guid>
            <pubDate>Wed, 21 May 2008 04:00:00 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/6.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2008/05/21/6.aspx#feedback</comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/6.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Solving Real Problems with Access Modifiers 101</title>
            <link>http://blog.kellybrownsberger.com/archive/2008/04/16/10.aspx</link>
            <description>&lt;p&gt;Its refreshing when you solve what appears to be a nasty problem with a simple and clean solution.  It's an even better feeling when you solve it with Computer Science fundamentals.  I solved something this morning by releaning how acces modifiers work (access modifiers in C# in my case).&lt;/p&gt;
&lt;p&gt;We have a basic data transfer object that has some private state that handles change tracking.  Something such as:&lt;/p&gt;
&lt;div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; height: 342px; background-color: rgb(244, 244, 244); max-height: 200px;"&gt;
&lt;div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   1:&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; ProductDTO&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   3:&lt;/span&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; _isDirty = &lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   4:&lt;/span&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; _name;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   5:&lt;/span&gt;     &lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   6:&lt;/span&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; Name&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   7:&lt;/span&gt;     {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   8:&lt;/span&gt;         get { &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; _name; }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   9:&lt;/span&gt;         set&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  10:&lt;/span&gt;         {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  11:&lt;/span&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; ( &lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt; != _name )&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  12:&lt;/span&gt;             {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  13:&lt;/span&gt;                 _name = &lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  14:&lt;/span&gt;                 _isDirty = &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  15:&lt;/span&gt;             }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  16:&lt;/span&gt;         }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  17:&lt;/span&gt;     }&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  18:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This of course is a contrived example, but it illustrates the crux of my problem.&lt;/p&gt;
&lt;p&gt;The &lt;font face="Courier New"&gt;_isDirty&lt;/font&gt; flag is managed internally and marked private as you'd expect.  What I need to do is transfer state from one instance of ProductDTO to another.  I need the public state as well as the private/internal state.  Over the years I've been lulled into thinking of private members as things that cannot be accessed outside of an &lt;em&gt;instance&lt;/em&gt;.  This isn't true.  Private members cannot be accessed outside of the &lt;em&gt;class&lt;/em&gt;.  In other words, two instances of the same class can happily access each other's private/internal members.  &lt;/p&gt;
&lt;p&gt;With this lesson relearned, I'm able to create a &lt;font face="courier n"&gt;Copy()&lt;/font&gt; method such as:&lt;/p&gt;
&lt;div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; height: 129px; background-color: rgb(244, 244, 244); max-height: 200px;"&gt;
&lt;div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   1:&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Copy(ProductDTO copy)&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   3:&lt;/span&gt;     _name = copy.Name;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   4:&lt;/span&gt;     _isDirty = copy._isDirty;&lt;/pre&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note the get of the _isDirty from the copy instance.&lt;/p&gt;
&lt;p&gt;I'd forgotten this how Access Modifiers work and from the majority of code I've seen in recent years, most developers out there have as well.  You typically see numerous forms of encapsulation violation or leaky public contracts to accomplish something like this.&lt;/p&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/10.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2008/04/16/10.aspx</guid>
            <pubDate>Wed, 16 Apr 2008 04:00:00 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/10.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2008/04/16/10.aspx#feedback</comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/10.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Microsoft IoC and Dependency Injection</title>
            <link>http://blog.kellybrownsberger.com/archive/2008/04/10/12.aspx</link>
            <description>&lt;p&gt;Microsoft's developer division has been making a lot interesting moves lately.  They're starting to finally listen to the strong thoughts and opinions coming out of the Java converts in the .NET community and realizing they know what they're talking about.  As usual, they're not really innovating, but they're taking existing ideas and building some great tooling around those ideas and delivering them to the masses.&lt;/p&gt;
&lt;p&gt;In the March release of MSDN Magazine they published &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/magazine/cc337885.aspx"&gt;&lt;em&gt;Loosen Up&lt;/em&gt;&lt;/a&gt; which is a general overview of the benefits of IoC and DI.  Just last week Microsoft Pattern's and Practices group released &lt;a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?familyid=6a9e363c-8e0a-48d3-bbe4-c2f36423e2df&amp;amp;displaylang=en"&gt;Unity&lt;/a&gt; - their entry into the IoC and DI space.  &lt;a target="_blank" href="http://www.martinfowler.com/articles/injection.html"&gt;Inversion of Control Containers and the Dependency Injection pattern&lt;/a&gt; are not new ideas and with &lt;a target="_blank" href="http://www.castleproject.org/container/index.html"&gt;Castle Windsor&lt;/a&gt;, &lt;a target="_blank" href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt; and &lt;a target="_blank" href="http://structuremap.sourceforge.net/Default.htm"&gt;StructureMap&lt;/a&gt; there are many seasoned IoC offerings out there already.&lt;/p&gt;
&lt;p&gt;I've been a big fan for StructureMap for it's simplicity.  From my initial experience with Unity, it has that same thinness and simplicity.  Now that it's from Microsoft, hopefully the Morts will start to pay attention to some of these important design concepts.&lt;/p&gt;
&lt;p&gt;David Hayden has a pretty great overview of Unity in screencast form &lt;a target="_blank" href="http://www.pnpguidance.net/Screencast/UnityIoCDependencyInjectionASPNETMVCFrameworkScreencast.aspx"&gt;here&lt;/a&gt;.  Download it and play it in Windows Media Player at double the speed (a handy trick I picked up from Scott Hanselman)&lt;/p&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/12.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2008/04/10/12.aspx</guid>
            <pubDate>Thu, 10 Apr 2008 04:00:00 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/12.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2008/04/10/12.aspx#feedback</comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/12.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Current Reading</title>
            <link>http://blog.kellybrownsberger.com/archive/2008/02/03/13.aspx</link>
            <description>&lt;p&gt;I haven't blogged in a long, long time.  I'm not sure what got me off the horse exactly, but it's time to get back on.&lt;/p&gt;
&lt;p&gt;Recently a past coworker from my Avanade days joined our team at CSG.  It's great to have him aboard, but it was a blast from the past for me being around him in a workplace setting.  I brought back a lot of memories of the consulting days.  Comparing and constrasting current myself with my 18-months-ago self was a little shocking.  I'm definitely much less of a Microsoft koolaide drinker and I'm certainly much less interested in the bleeding edge.  I'm getting to the point in my career where I'm seeing the cyclical trends in technology and I'm catching myself choosing to sit out a wave or two here and there.&lt;/p&gt;
&lt;p&gt;My focus for the last year has been building software in an Agile fashion.  Said a different way, I'm 100% engrossed in how to build software that's easy to change.  I've spent my entire career with my feet firmly planted in the Microsoft camp and I definitely am committed to my platform of choice, but I'm frequently disappointed with in the fundamental skills on our community.  We're starting to see that most of the important thinking in the Microsoft space is being done by Java converts.  I'm currently reading &lt;a href="http://www.amazon.com/Principles-Patterns-Practices-Robert-Martin/dp/0131857258" target="_blank"&gt;Agile Principles, Patterns, and Practices in C#&lt;/a&gt; by Robert Martin.  It is a wonderful introduction to the art of building software that's easy to change.  Sadly, much of the Microsoft .NET development community, as Martin points out in the foreword, is lacking in many of the core Object Oriented design fundamentals.  Apparently he specifically wrote this C# specific revision to his classic &lt;a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1202070667&amp;amp;sr=1-2" target="_blank"&gt;Agile Principles, Patterns, and Practices&lt;/a&gt; book just to get the attention of the Microsoft camp.&lt;/p&gt;
&lt;p&gt;Check it out - great stuff here for all ages&lt;/p&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/13.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2008/02/03/13.aspx</guid>
            <pubDate>Sun, 03 Feb 2008 05:00:00 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/13.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2008/02/03/13.aspx#feedback</comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/13.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Introduction to Subversion</title>
            <link>http://blog.kellybrownsberger.com/archive/2007/05/13/14.aspx</link>
            <description>&lt;p&gt;Long ago I married myself to the Microsoft technology stack.  For a long long, that meant you were a Visual Source Safe user.  VSS's suckiness is well known and well documented.  I've been happily using the free license for SourceGear Vault at home for the last 3 years and professionally I've been using whatever my clients had in place (VSS, Vault, or Team Foundation usually).  When I came to CSG in late 2006, I was introduced to Subversion (SVN).  I'd certainly read about SVN and knew it was a very popular open source source control system.  While the adjustment period was a little rocky (mainly getting used to a merge based check-in approach around the team instead of exclusive checkouts).&lt;/p&gt;
&lt;p&gt;Like almost everyone that's used it for any significant period of time, I'm a SVN lover.  I've been using it at work for 6 months, but knew nothing about setting it up.  This weekend I gutted out Vault, and stood up a SVN Server on my home network.  For someone used to Microsoft products, you don't like installations filled with editing text files and commandlines.  While it's not as polished as a MS install, the whole thing was relatively painless.  Because my target host was a windows box, I was a bit worried about dipping my toes into Apache and all that comes with it.  Well, let me say - all that *might* come with it.  I'm used to IIS based servers and MS does a good job of hiding all of that from me on install.  Thankfully, I didn't have to think about Apache once.  Below are some posts that detail the installation process if you're interested in going down this path, but at a high level, this is what you need to do.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Download and run the SVN installer&lt;/li&gt;
    &lt;li&gt;Download and run the SVNService installer - handy Windows Service that wraps up SVN nicely in the Windows world.&lt;/li&gt;
    &lt;li&gt;Download and run TortoiseSVN install - this is the server client (one of many available)
    &lt;ul&gt;
        &lt;li&gt;If you've never used anything but VSS before, this will be new to you.  SVN is a file system based source control system.  Each use has a copy of the source on their local file system.  The source is freely change locally and at the time you check you, you merge the source into the "trunk"&lt;/li&gt;
        &lt;li&gt;SVN has a commandline based interface for performing checkin's, but TortoiseSVN is Windows shell extension that gives you a GUI for performining checkins.  It's bound to the windows shell and has icon overlays to notifying you when something's been changed (since the last GET from the server - called an SVN Update).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Created a default respository in SVN (see links below)&lt;/li&gt;
    &lt;li&gt;Configured SVNService
    &lt;ul&gt;
        &lt;li&gt;TIP:  By default SVNService tries to configure itself to listen as LOCALHOST.  This will cause problem if you plan to access the server remotely from another machine.  Make sure to configure SVNService as listening as the machine name hosting the SVN server.&lt;/li&gt;
        &lt;li&gt;You'll see posts all over the net complaining about "No connection could be made because the target machine actively refused it" errors.  I never found a good reply on any of the sites.  Knowing a little bit about Windows Services and Windows TCP/IP, I knew what the problem was.  Run the SVNService admin tool and make sure you're not listening as LOCALHOST.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Setup SVN security
    &lt;ul&gt;
        &lt;li&gt;This is all text file based in the repository directory.  Just be patient and read the comments at the top of the config files and you'll figure it out pretty quickly.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Install all TortoiseSVN on all the client you want to access your server with and checkout the repository using TortoiseSVN's repo browser - svn://your-server/your_repos&lt;/li&gt;
    &lt;li&gt;Setup remote access
    &lt;ul&gt;
        &lt;li&gt;I wanted remote access outside of my network.  SVN supports HTTP natively, but I've decided to use the SVN native protocol first and if it doesn't prove sufficient for my remote needs, I"ll get HTTP working, but for now, I seem good without HTTP&lt;/li&gt;
        &lt;li&gt;I setup routing record on my main router to route all traffic on port 3690 to my SVN server.&lt;/li&gt;
        &lt;li&gt;Now I can access my SVN server from TortoiseSVN from my office using svn://svn.kellybrownsberger.com/main/dev_repos.  Very cool&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Checkout these links for more detail - as usual with open source, get used to a lot of dead links and ugly hacker forum sites.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.vertigosoftware.com/teamsystem/archive/2006/01/16/Setting_up_a_Subversion_Server_under_Windows.aspx" target="_blank"&gt;Setting up a Subversion Server under Windows&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://amsn-project.net/wiki/SVN" target="_blank"&gt;Installing SVN&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blog.kellybrownsberger.com/aggbug/14.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>kellyb</dc:creator>
            <guid>http://blog.kellybrownsberger.com/archive/2007/05/13/14.aspx</guid>
            <pubDate>Sun, 13 May 2007 04:00:00 GMT</pubDate>
            <wfw:comment>http://blog.kellybrownsberger.com/comments/14.aspx</wfw:comment>
            <comments>http://blog.kellybrownsberger.com/archive/2007/05/13/14.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.kellybrownsberger.com/comments/commentRss/14.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>