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

<channel>
	<title>Aaron Lerch &#187; .net</title>
	<atom:link href="http://www.aaronlerch.com/blog/category/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.aaronlerch.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 04 Dec 2011 03:27:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Two Components for your Toolbox</title>
		<link>http://www.aaronlerch.com/blog/2009/09/25/two-components-for-your-toolbox/</link>
		<comments>http://www.aaronlerch.com/blog/2009/09/25/two-components-for-your-toolbox/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 06:36:11 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2009/09/25/two-components-for-your-toolbox/</guid>
		<description><![CDATA[Any desktop application I write from now on will contain these two interfaces. They’re useful enough I thought I should share. Also note, with upcoming improvements in .NET 4.0 (or higher) they might be rendered moot. So far, I don’t think they are, as it’s still difficult to test the code itself that performs asynchronous [...]]]></description>
			<content:encoded><![CDATA[<p>Any desktop application I write from now on will contain these two interfaces. They’re useful enough I thought I should share. Also note, with upcoming improvements in .NET 4.0 (or higher) they might be rendered moot. So far, I don’t think they are, as it’s still difficult to test the code itself that performs asynchronous operations.</p>
<p>First, is an abstraction around the User Interface thread, IUserInterfaceContext. This exists today in the form of <a href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx">SynchronizationContext</a>, but I favor this specific interface because</p>
<ol>
<li>It’s more explicit (the SynchronizationContext applies to more than just the main UI thread) whereas this is very clear what its purpose is.</li>
<li>The API is cleaner – passing a “state” is unnecessary with nested closures.</li>
<li>It’s easier to grab out of an IoC container. Because a SynchronizationContext is only specific to the context it was created in (which could be a background thread) it’s not meaningful to put a SynchronizationContext argument in your constructor. Which one do you want?</li>
</ol>
<pre class="brush: csharp;">public interface IUserInterfaceContext
{
    void Execute(Action action);
    void ExecuteAndBlock(Action action);
}</pre>
<p>Now, any component in my application can execute code on the UI thread extremely easily. I just register the implementation of IUserInterfaceContext (which does use a SynchronizationContext) when my application is started, which is on the UI thread.</p>
<p>The implementation could look something like this:</p>
<pre class="brush: csharp;">public class UserInterfaceContext : IUserInterfaceContext
{
    private readonly SynchronizationContext _syncContext;

    public UserInterfaceContext(SynchronizationContext syncContext)
    {</pre>
<pre class="brush: csharp;">        /* Ensure the SynchronizationContext passed in is the main UI thread context */
        _syncContext = syncContext;
    }

    public void ExecuteAndBlock(Action action)
    {
        if (_syncContext != null)
        {
            _syncContext.Send(s =&gt; action(), null);
        }
        else
        {
            action();
        }
    }

    /// &lt;inheritdoc /&gt;
    public void Execute(Action action)
    {
        if (_syncContext != null)
        {
            _syncContext.Post(s =&gt; action(), null);
        }
        else
        {
            ThreadPool.QueueUserWorkItem(s =&gt; action(), null);
        }
    }
}</pre>
<p>Secondly, is a more generalized example of Jeremy Miller’s <a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/02/15/build-your-own-cab-18-the-command-executor.aspx">ICommandExecutor</a>, which is even more generalized as the <a href="http://blog.gurock.com/postings/active-objects-and-futures-a-concurrency-abstraction-implemented-for-c-and-net/290/">Active Object pattern</a>. I named mine “IAsyncExecutor” because it executes any code asynchronously. The advantage with this approach is that it drastically simplifies test activities to be able abstract multithreading (to a point) and allow a test to run single threaded. That is nothing but pure win. We’ve also found that using the interface makes the code read better than using a bunch of BeginInvoke/EndInvoke’s or the ThreadPool, or an async pattern such as &#8220;void FooAsync(AsyncCallback callback, object state);</p>
<pre class="brush: csharp;">public interface IAsyncExecutor
{
    void Execute(Action action);
    void Execute(Action action, Action after, bool callbacksOnUIThread);
    void Execute(Action action, Action after, Action&lt;Exception&gt; error, bool callbacksOnUIThread);
}</pre>
<p>You’ll notice that IAsyncExecutor looks a lot like IUserInterfaceContext, and in fact, it can use it under the covers if the callbacksOnUIThread is true.</p>
<p>Both of these are simple interfaces, with trivial implementations, but you’d be surprised how often I’ve wished I’ve had them in the past. What are some “core” interfaces/services/etc that you <strong>*must have*</strong> in your toolbox?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2009/09/25/two-components-for-your-toolbox/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Say Hello to My Little Internet</title>
		<link>http://www.aaronlerch.com/blog/2009/08/20/say-hello-to-my-little-internet/</link>
		<comments>http://www.aaronlerch.com/blog/2009/08/20/say-hello-to-my-little-internet/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 07:20:42 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[services]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2009/08/20/say-hello-to-my-little-internet/</guid>
		<description><![CDATA[Recently I’ve been thinking about options for exposing an application automation API for inter process integration scenarios. For example, a desktop application that exposes the ability for other applications to programmatically query information from it and/or invoke commands. I also had a few requirements. Whatever I choose should: Let me inject core application services (or [...]]]></description>
			<content:encoded><![CDATA[<p><img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://s3.amazonaws.com:80/aaronlerch.com/Scarface.png" />Recently I’ve been thinking about options for exposing an application automation API for inter process integration scenarios. For example, a desktop application that exposes the ability for other applications to programmatically query information from it and/or invoke commands. I also had a few requirements. Whatever I choose should:</p>
<ul>
<li>Let me inject core application services (or higher level aggregated services, or ANYTHING I WANT) by pulling them out of my IoC container </li>
<li>Not require the service to run in a new AppDomain </li>
<li>Be easy to use, configure, and integrate into my application </li>
<li>Be testable </li>
</ul>
<p>I’m going down the path of exposing a Web API (I would call it a RESTful service, but really it’s not). Of course my first stop was to investigate hosting ASP.NET MVC in a desktop application (which really just means hosing ASP.NET). There are a few <a href="http://www.west-wind.com/presentations/aspnetruntime/aspnetruntime.asp">articles</a> <a href="http://www.codeproject.com/KB/dotnet/usingaspruntime.aspx">out</a> there about how to do this, and for the “intended” scenario, it’s pretty easy.</p>
<p>Unfortunately the “intended” scenario is web hosting, which loads everything into a new AppDomain. And aside from some of the outer classes and factories, everything is marked private or internal so I can’t get at it without doing a bunch of reflection. Bah.</p>
<p>I’ve ended up taking a long look at <a href="http://www.openrasta.com/">OpenRasta</a>. OpenRasta was written with DI/IoC in mind, and it actually uses an internal IoC container for configuring the framework. More on that in a future post. It also has it’s own hosting support and API that have out-of-the-box implementations for ASP.NET, <a href="http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx">HttpListener</a>, and “In Memory”. But you could always implement your own hosting code and integrate it.</p>
<p>The key word in that entire paragraph was “HttpListener”. That’s built-in .NET support for for web request processing that is baked into Windows via the kernel-mode http.sys driver. It’s relatively easy to use, and it’s wonderful. OpenRasta integrates with my existing application infrastructure, and marries it up with support for a REST-style web API, enabling me to very quickly expose a web API that allows third parties to integrate with my application. This is going to be more and more important as things like Windows Gadgets are implemented which are restricted in terms of the kinds of ways they can communicate (web requests) and with whom they can communicate (localhost, etc.)</p>
<p>Unfortunately OpenRasta doesn’t support <a href="http://ninject.org/">Ninject</a>, which I use, so I’m implementing the support for it and will submit the patch soon.</p>
<p>So far I’m extremely happy with the solution as I think developer productivity will be through the roof (compared to other more invasive solutions like WCF) and client-side integrations won’t be that difficult (POX). For my scenario, it’s all right up my alley. The internetz work for ME now!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2009/08/20/say-hello-to-my-little-internet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging UI</title>
		<link>http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/</link>
		<comments>http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 19:01:09 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[windows forms]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/</guid>
		<description><![CDATA[I&#8217;ve talked before about System.Threading.SynchronizationContext, as well as BeginInvoke/InvokedRequired/IsHandleCreated. In a multi-threaded Windows Forms application they can easily be mis-used, introducing difficult to find bugs. One such not-so-subtle bug (application hang) is particularly nasty, and is described fairly well here. Distilled down, the application hangs, usually when the computer comes out of sleep mode, unlocks, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve talked before about <a href="http://www.aaronlerch.com/blog/2007/05/19/net-20-winforms-multithreading-and-a-few-long-days/">System.Threading.SynchronizationContext</a>, as well as <a href="http://www.aaronlerch.com/blog/2006/12/15/controltrifecta-invokerequired-ishandlecreated-and-isdisposed/">BeginInvoke/InvokedRequired/IsHandleCreated</a>. In a multi-threaded Windows Forms application they can easily be mis-used, introducing difficult to find bugs.</p>
<p>One such not-so-subtle bug (application hang) is particularly nasty, and is <a href="http://ikriv.com:8765/en/prog/info/dotnet/MysteriousHang.html">described fairly well here</a>. Distilled down, the application hangs, usually when the computer comes out of sleep mode, unlocks, or another similar event occurs. The hang happens in the firing of an event handler, called from &#8220;SystemEvents.OnUserPreferenceChanged&#8221;. The cause is that OnUserPreferenceChanged is trying to be super nice, and invoke the event in the appropriate context for each event subscriber. That means that if a Control subscribes to the event, the handler will be called on the UI thread. If user code (on a background thread) subscribes, the handler will be called on an arbitrary thread, etc. The problem occurs when, at some point in the past, a Form or Control was created on a background thread. The creation of the control &#8220;installed&#8221; a WindowsFormsSynchronizationContext as the current SynchronizationContext (this is default behavior). When OnUserPreferenceChanged attempts to Send (Invoke) to the appropriate thread context, it hangs because the WindowsFormsSynchronizationContext is on the wrong thread, and thus has no message pump with which to process messages.</p>
<p>Blah blah blah. Right now you&#8217;re thinking &#8220;Whatever dude, I&#8217;m a web developer, man, I&#8217;m just trying to fix this bug in that <strong>other</strong> jerk&#8217;s code.&#8221; Fair enough, you can read the linked post for more gory details. What you care about is the hard part. Well, hard for <em>web developers</em> anyway. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  By the time the app hangs, it&#8217;s too late to find out where the problem occurred. In a medium-to-large application, how do you find the control that was created on the wrong thread? Here&#8217;s how to do it in a matter of seconds.</p>
<p><strong>1. Name your UI thread.</strong> If you&#8217;re not already doing this, it&#8217;s a good idea in general. I like to call mine &#8220;UI&#8221;, personally. In your &#8220;static void Main()&#8221; add this single line of code:</p>
<pre class="c#" name="code">Thread.CurrentThread.Name = "UI";</pre>
<p><strong>2. Set a breakpoint deep in the bowels of the BCL.</strong> What we want to do is cause our application to break when a WindowsFormsSynchronizationContext gets assigned to the current thread. I cracked open Reflector to look at the constructor for WindowsFormsSynchronizationContext:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/winforms_synccontext_ctor.png"></p>
<p>And I see that there&#8217;s a call to &#8220;Application.ThreadContext.FromCurrent()&#8221;. Close enough for government work, it&#8217;ll do for what I want. I didn&#8217;t feel like figuring out how to specify a constructor call when setting a breakpoint. (If you know how, leave a comment so we can all learn!) Add a breakpoint to that method call. In Visual Studio, go to the &#8220;Debug&#8221; &gt; &#8220;New Breakpoint&#8221; &gt; &#8220;Break at Function&#8230;&#8221; menu. In the &#8220;Function&#8221; area type the full path to the function: System.Windows.Forms.Application.ThreadContext.FromCurrent()</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/new_breakpoint_threadcontext.png"></p>
<p>When you hit &#8220;OK&#8221; you&#8217;ll get a warning about IntelliSense not finding the specified location. Hit &#8220;Yes&#8221; to set the breakpoint anyway.</p>
<p><strong>3. Run your application.</strong> Depending on what version of Visual Studio you&#8217;re running, and whether you&#8217;ve got source-level debugging for the Framework turned on, you&#8217;ll either get the breakpoint on some code, or you&#8217;ll get this message box:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/no_source_code_msgbox.png"></p>
<p>It doesn&#8217;t matter, you can press &#8220;OK&#8221; or &#8220;Show Disassembly&#8221;, whatever floats your boat. Go to the &#8220;Call Stack&#8221; debugging window, right-click on the red breakpoint circle located at the top of the stack frame, and select &#8220;Breakpoint&#8221; &gt; &#8220;Filter&#8230;&#8221;</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/breakpoint_filter.png"></p>
<p><strong>4. Add a filter to this breakpoint so that it only breaks when the current threads&#8217; name isn&#8217;t &#8220;UI&#8221;.</strong></p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/breakpoint_filter_non_ui_thread.png"></p>
<p>After you hit &#8220;OK&#8221;, continue running your application in the debugger. The first time a WindowsFormsSynchronizationContext is created and it&#8217;s not on the UI thread, BAM. There&#8217;s your problem, and there&#8217;s your stack trace allowing you to find the bad code.</p>
<p>This worked like a champ for me today, hopefully you have as much success with it too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Case insensitive string comparisons with LINQ Dynamic Query</title>
		<link>http://www.aaronlerch.com/blog/2008/12/15/case-insensitive-string-comparisons-with-linq-dynamic-query/</link>
		<comments>http://www.aaronlerch.com/blog/2008/12/15/case-insensitive-string-comparisons-with-linq-dynamic-query/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 07:46:37 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/12/15/case-insensitive-string-comparisons-with-linq-dynamic-query/</guid>
		<description><![CDATA[LINQ rocks. It really does. One down-side to LINQ is that, out of the box, it&#8217;s geared towards knowing your query structure at compile-time. The values can be dynamic, of course, but it&#8217;s assumed that the structure of your query is static. For example, if you want to select a set of &#34;Person&#34; objects from [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/vbasic/aa904594.aspx">LINQ</a> rocks. It really does.</p>
<p>One down-side to LINQ is that, out of the box, it&#8217;s geared towards knowing your query structure at compile-time. The values can be dynamic, of course, but it&#8217;s assumed that the structure of your query is static. For example, if you want to select a set of &quot;Person&quot; objects from the &quot;People&quot; collection where Person.FirstName starts with &quot;Aar&quot;, you could write it as such:</p>
<pre class="c#" name="code">var results = from person in People
              where person.FirstName.StartsWith(&quot;Aar&quot;)
              select person;</pre>
<p>That&#8217;s all fine and good, but what about scenarios where you want to dynamically build up your query structure? In <a href="http://www.inin.com/">our</a> client application we have address books (directories) that include the ability to filter them on any, or nearly any, column:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/client_directory_filter.png" /></p>
<p>How would I accomplish this with LINQ? Not easily. Just ask <a href="http://www.google.com/search?q=expression+tree+site:ayende.com">Ayende</a> or <a href="http://www.google.com/search?q=expression+tree+site:blog.wekeroad.com">Rob Conery</a>, both of whom have blogged about some of their adventures in advanced usage scenarios. Enter the LINQ Dynamic Query sample from Microsoft. As usual, <a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx">ScottGu&#8217;s got a good write-up</a>. In a nutshell, it&#8217;s a custom expression tree generator based on a limited (but useful) string-based query grammar. With Dynamic Query I could write the query above like this:</p>
<pre class="c#" name="code">var results = from person in People
              select person;
results = results.Where(&quot;FirstName.StartsWith(\&quot;Aar\&quot;)&quot;);</pre>
<p>It solved my problem nicely. Almost. As with my example above about matching FirstName&#8217;s, let me ask: how often does a user enter an exact case-sensitive match for what they&#8217;re looking for? I can save you the trouble and tell you: it doesn&#8217;t matter. It&#8217;s an unacceptable requirement for a user to have to match something exactly. It&#8217;s already questionable that we don&#8217;t automatically use fuzzy matching algorithms.</p>
<p>So what I really want is to specify a StringComparison enum value on the call to &quot;StartsWith&quot;:</p>
<pre class="c#" name="code">var results = from person in People
              select person;
results = results.Where(&quot;FirstName.StartsWith(\&quot;Aar\&quot;, System.StringComparison.OrdinalIgnoreCase)&quot;);</pre>
<p>Alas, this breaks. LINQ Dynamic Query doesn&#8217;t support enum values as parameters to methods. <em>So I added it.</em> I won&#8217;t redistribute the sample (I&#8217;m pretty sure I can&#8217;t, but I don&#8217;t care to anyway) so here&#8217;s what you need to do to add support for enum parsing. Note that I&#8217;ve only tested it with calls to string&#8217;s StartsWith(string, StringComparison) method. I don&#8217;t know what will happen if you sprinkle enum values in random places throughout your dynamic query. Work on My Machine, your mileage may vary, etc. etc. etc.</p>
<p><strong>1.</strong> <a href="http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx">Download the sample.</a></p>
<p><strong>2.</strong> Crack open the Dynamic.cs source file. It&#8217;s scary, but you can do it. Modify it like so (I added the &quot;if (ParseEnumType&#8230;&quot;</p>
<pre class="c#" name="code">Expression ParseIdentifier() {
    ValidateToken(TokenId.Identifier);
    object value;
    if (keywords.TryGetValue(token.text, out value)) {
        if (value is Type) return ParseTypeAccess((Type)value);
        if (value == (object)keywordIt) return ParseIt();
        if (value == (object)keywordIif) return ParseIif();
        if (value == (object)keywordNew) return ParseNew();
        NextToken();
        return (Expression)value;
    }
    if (symbols.TryGetValue(token.text, out value) ||
        externals != null &amp;&amp; externals.TryGetValue(token.text, out value)) {
        Expression expr = value as Expression;
        if (expr == null) {
            expr = Expression.Constant(value);
        }
        else {
            LambdaExpression lambda = expr as LambdaExpression;
            if (lambda != null) return ParseLambdaInvocation(lambda);
        }
        NextToken();
        return expr;
    }
    // ADD THIS IF STATEMENT
    if (ParseEnumType(out value))
    {
        Expression expr = Expression.Constant(value);
        NextToken();
        return expr;
    }
    if (it != null) return ParseMemberAccess(null, it);
    throw ParseError(Res.UnknownIdentifier, token.text);
}</pre>
<p><strong>3.</strong> Add the definition for ParseEnumType. This little bit of nastiness is essentially doing a look-ahead to resolve a type name, since most of the parser&#8217;s rules are built to process more contextual information (such as a property name of a type, etc.) In our case, we need to attempt to match &quot;Foo.Foo.Foo&quot; to a type name, and if it doesn&#8217;t end up resolving, we need to reset the parser back to the beginning of &quot;Foo&quot; to continue parsing.</p>
<pre class="c#" name="code">bool ParseEnumType(out object value)
{
    value = null;

    ValidateToken(TokenId.Identifier);
    Type enumType = null;
    int position = token.pos;
    string typeName = token.text;
    while (enumType == null)
    {
        // Loop until we stop processing identifiers and/or dots
        enumType = Type.GetType(typeName, false, true);
        if (enumType == null)
        {
            NextToken();
            if (token.id == TokenId.Dot)
            {
                typeName += token.text;
                NextToken();
                if (token.id == TokenId.Identifier)
                {
                    typeName += token.text;
                }
                else
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }
    }

    if ((enumType != null) &amp;&amp; IsEnumType(enumType))
    {
        NextToken();
        ValidateToken(TokenId.Dot, Res.DotExpected);
        NextToken();
        ValidateToken(TokenId.Identifier, Res.IdentifierExpected);
        value = Enum.Parse(enumType, token.text, true);
        return true;
    }
    else
    {
        SetTextPos(position);
        NextToken();
    }

    return false;
}</pre>
<p><strong>4.</strong> Add an error &quot;resource&quot; string (but not really a true resource string) to the &quot;Res&quot; static class. We added a new condition, so we need an error message to match.</p>
<pre class="c#" name="code">public const string DotExpected = &quot;'.' expected&quot;;</pre>
<p>Voila! Make sure your enum values are fully-qualified type names and you&#8217;ll be good to go.</p>
<p>Hopefully this works for you as well as it did for me, and I have to say I can&#8217;t believe I couldn&#8217;t find this on the &#8216;net, as I imagine this is a very common use-case.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/12/15/case-insensitive-string-comparisons-with-linq-dynamic-query/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Testing TempData, and Mocking SessionState</title>
		<link>http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/</link>
		<comments>http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 00:07:10 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[asp.net mvc]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/</guid>
		<description><![CDATA[About a month and a half ago Ben Scheirman wrote about testing TempData in ASP.NET MVC. It&#8217;s good stuff, and aside from changes between Preview 1 and Preview 2, it still works fine. (See Scott Hanselman&#8217;s post for some Preview 2-friendly mock helpers using Rhino Mocks.) While I can easily understand what Ben&#8217;s code is [...]]]></description>
			<content:encoded><![CDATA[<p>About a month and a half ago <a href="http://flux88.com/">Ben Scheirman</a> wrote about <a href="http://flux88.com/testingtempdatainaspnetmvc.aspx">testing TempData in ASP.NET MVC</a>. It&#8217;s good stuff, and aside from changes between Preview 1 and Preview 2, it still works fine. (See <a href="http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx">Scott Hanselman&#8217;s post</a> for some Preview 2-friendly mock helpers using Rhino Mocks.)</p>
<p>While I can easily understand what Ben&#8217;s code is doing, what I couldn&#8217;t figure out is <em>why</em> it worked. If you reflect over TempDataDictionary (the type of the Controller.TempData property), you&#8217;ll see that the data type it persists to the session is an internal structure.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/tempdata-reflector.png" /></p>
<p>Ben&#8217;s code, however, mocks out the Session to return the expected TempDataDictionary object. By all counts, that should fail, since the TempDataDictionary won&#8217;t be getting back the values it expects&#8211;it expects the internal map structure.</p>
<p>Well, it turns out I was glossing over one very important fact. TempDataDictionary was written to be smart enough that if the underlying session store either didn&#8217;t work, or didn&#8217;t provide the right data, TempData will continue to operate as normal&#8211;<em>for the current request only</em>. You can see below that if the session data was null or wasn&#8217;t the right type, it just creates a new internal map.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/tempdata-reflector2.png" /><br />
<font size="1">(image cut off for space)</font></p>
<p>One of the benefits of TempData is the cross-request persistence via the session. You might not have known it, but when you call RedirectToAction in your controller action, for example, it&#8217;s actually resulting in a 300-level HTTP redirect, which means an entirely new HttpContext for the next request. It&#8217;s basically deferring to the browser to perform the redirect.</p>
<p>So, while Ben&#8217;s code will definitely work, here&#8217;s an extension method that can help with mocking out the session a little more &#8220;correctly&#8221;:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> NullifySessionState(<span class="kwrd">this</span> HttpSessionStateBase session)
{
    SetupResult.For(session[<span class="kwrd">null</span>]).IgnoreArguments().Return(<span class="kwrd">null</span>);
    session[<span class="kwrd">null</span>] = <span class="kwrd">null</span>;
    LastCall.IgnoreArguments();
}</pre>
<style type="text/css">.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; }</style>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>S3 Browser for Windows Live Writer</title>
		<link>http://www.aaronlerch.com/blog/2008/03/10/s3-browser-for-windows-live-writer/</link>
		<comments>http://www.aaronlerch.com/blog/2008/03/10/s3-browser-for-windows-live-writer/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 01:25:00 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/03/10/s3-browser-for-windows-live-writer/</guid>
		<description><![CDATA[Tim Heuer announced today the release of &#8220;S3 Browser&#8221;, a plug-in for Windows Live Writer that enables easy inserting of links or images from your S3 storage. See his announcement on his blog, and on the Code Trip&#8217;s blog. Like Tim, I&#8217;ve been using S3 to host my images for the blog, and I wholeheartedly [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://s3.amazonaws.com/aaronlerch.com/images/s34writer.png" align="right" /><a href="http://timheuer.com/">Tim Heuer</a> announced today the release of &#8220;S3 Browser&#8221;, a plug-in for Windows Live Writer that enables easy inserting of links or images from your S3 storage. See his <a href="http://timheuer.com/blog/archive/2008/03/10/amazon-s3-plugin-for-windows-live-writer.aspx">announcement on his blog</a>, and on <a href="http://thecodetrip.com/1/s3browser-for-live-writer">the Code Trip&#8217;s blog</a>.</p>
<p>Like Tim, I&#8217;ve been using S3 to host my images for the blog, and I wholeheartedly agree with him &#8211; the workflow for writing a post sucked <em>big time</em>. This plug-in had been on my <font color="#008000">//TODO</font> list for a long while now. Somehow I mentioned that fact to Tim on <a href="http://twitter.com/aaronlerch">Twitter</a> and he sent me a link to a screenshot of his initial version. My response? Sign me up!</p>
<p>He uploaded his source to <a href="http://www.codeplex.com/s3browser">CodePlex</a> and I immediately started implementing the remaining features. The result is the 0.9 beta release of the S3 Browser Windows Live Writer plug-in. <a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=s3browser&amp;ReleaseId=11530">Give it a download</a> and try it out! Please submit any feature ideas or bugs on the codeplex site, or you can leave a comment here as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/03/10/s3-browser-for-windows-live-writer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Refactoring C# with PowerShell</title>
		<link>http://www.aaronlerch.com/blog/2008/01/04/refactoring-c-with-powershell/</link>
		<comments>http://www.aaronlerch.com/blog/2008/01/04/refactoring-c-with-powershell/#comments</comments>
		<pubDate>Fri, 04 Jan 2008 18:06:07 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/01/04/refactoring-c-with-powershell/</guid>
		<description><![CDATA[Visual Studio 2005 and 2008 have built-in support for refactoring code, including renaming namespaces, classes, variables, and more. Add-ins like Resharper also have support for refactoring by renaming. These tools work great, and have good integration into the Visual Studio IDE, for example being able to preview each change and exclude false positive matches. I [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.aaronlerch.com/files/blog/RefactoringCwithPowerShell_E201/image.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" alt="image" src="http://aaronlerch.com.s3.amazonaws.com/images/refactoring_with_powershell_screenshot_thumb.png" width="222" align="right" border="0" /></a>Visual Studio 2005 and 2008 have built-in <a href="http://msdn2.microsoft.com/en-us/library/ms379618(VS.80).aspx#vs05_refac_topic8">support for refactoring code</a>, including renaming namespaces, classes, variables, and more. Add-ins like <a href="http://www.jetbrains.com/resharper/">Resharper</a> also have support for <a href="http://www.jetbrains.com/resharper/features/code_refactoring.html#Rename_Symbol_full">refactoring by renaming</a>. These tools work great, and have good integration into the Visual Studio IDE, for example being able to preview each change and exclude false positive matches. I know many people swear by Resharper in particular (for more features than the refactoring alone).</p>
<p>Unfortunately all of these tools are restricted in one normally insignificant way: they only operate on the currently loaded project(s). For most software this really is insignificant. The entire application can be loaded into the IDE all at once. Sometimes, though, it is a problem&#8211;usually when there&#8217;s another problem at play: <a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html">code &quot;bloat&quot;</a> (<a href="http://www.moserware.com/2007/12/how-legacy-of-dead-mathematician-can.html">via Jeff</a>).</p>
<p>If you&#8217;ve ever changed a namespace and wanted to simply push the change into every code file in an entire directory branch, PowerShell comes to our rescue with it&#8217;s search-and-replace capabilities. I wrote the following &quot;Move-Namespace&quot; function to do just that.</p>
<p>Invoke the function like so: &quot;Move-Namespace *.cs &quot;[current namespace]&quot; &quot;[current class name]&quot; &quot;[new namespace]&quot;.</p>
<p>After it completes, any explicit reference will be changed, and any implicit references (using traditional &quot;using [namespace];&quot; statements) will have a new &quot;using [new namespace];&quot; line inserted after the last existing using statement.</p>
<p>Let&#8217;s hope you don&#8217;t have a code base that requires this function. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  But if you do, I hope it helps!</p>
<p><em>Note that this function relies on my &quot;Replace-String&quot; function, </em><a href="http://www.aaronlerch.com/blog/2007/03/28/powershell-replace-string-function/"><em>found here</em></a><em>.</em></p>
<pre class="csharpcode"><span class="kwrd">function</span> Move-Namespace(
    $includes = $(<span class="kwrd">throw</span> <span class="str">'Specify a file filter to use'</span>),
    $oldNamespace = $(<span class="kwrd">throw</span> <span class="str">'The namespace to replace - i.e. MyCompany.Product'</span>),
    $className = $(<span class="kwrd">throw</span> <span class="str">'The class name to search for - i.e. MyClass'</span>),
    $newNamespace = $(<span class="kwrd">throw</span> <span class="str">'The new namespace to add - i.e. MyCompany.Product.Feature'</span>))
{
    <span class="rem"># Look for cases of $className</span>
    <span class="rem"># or $oldNamespace.$className</span>
    <span class="rem"># and replace as necessary</span>

    <span class="rem"># First check for assumed &quot;using&quot; statements, and add the using statement</span>
    $results = @{}
    $files = get-childitem -r -i $includes | select-string <span class="str">&quot;(?&lt;!$oldNamespace\.)\b$className\b&quot;</span> -list |% { $_.Path }
    select-string <span class="str">&quot;^using.*;&quot;</span> -path $files | group-object Path | select-object Name, @{Expression={ ($_.Group | measure-object -property LineNumber -max).Maximum }; Name=<span class="str">&quot;LastUsingStatement&quot;</span> } |% { $results[$_.Name] = $_.LastUsingStatement }
    <span class="kwrd">foreach</span> ($key <span class="kwrd">in</span> $results.keys)
    {
      $processFile = $true
      $lastUsingIndex = $results[$key]
      $fileContents = get-content $key
      <span class="rem"># look for existing using statement and cancel processing this file</span>
      <span class="kwrd">for</span> ($i = 0; $i <span class="preproc">-lt</span> $lastUsingIndex; $i++)
      {
        <span class="kwrd">if</span> ($fileContents[$i] <span class="preproc">-match</span> <span class="str">&quot;using $newNamespace;&quot;</span>)
        {
          <span class="rem"># this file already has the correct using statement, stop processing</span>
          Write-Warning <span class="str">&quot;File $key already has the required using statement, ignoring&quot;</span>
          $processFile = $false
          <span class="kwrd">break</span>;
        }
      }

      <span class="kwrd">if</span> ($processFile)
      {
        $newContents = $fileContents[0..($lastUsingIndex-1)] + <span class="str">&quot;using $newNamespace;&quot;</span> + $fileContents[$lastUsingIndex..$fileContents.Length]
        set-content -path $key -value $newContents
        Write-Host <span class="str">&quot;Successfully updated file $key&quot;</span> -foregroundcolor Green
      }
    }

    <span class="rem"># Next check for explicit references</span>
    replace-string <span class="str">&quot;\b$oldNamespace\.$className\b&quot;</span> <span class="str">&quot;$newNamespace.$className&quot;</span> $includes
}</pre>
<style type="text/css">
<p>.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; }</style>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/01/04/refactoring-c-with-powershell/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Symbol Store Manager &#8211; open source and a beta release</title>
		<link>http://www.aaronlerch.com/blog/2007/12/30/symbol-store-manager-open-source-and-a-beta-release/</link>
		<comments>http://www.aaronlerch.com/blog/2007/12/30/symbol-store-manager-open-source-and-a-beta-release/#comments</comments>
		<pubDate>Sun, 30 Dec 2007 22:18:04 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[Symbol Store Manager]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2007/12/30/symbol-store-manager-open-source-and-a-beta-release/</guid>
		<description><![CDATA[A while ago I &#34;released&#34; the Symbol Server Transaction Manager. It was a binaries-only, quick-and-dirty GUI wrapper utility I wrote on top of the symstore.exe command-line tool, at the prompting of John Robbins. If you&#8217;re not familiar with Symbol Servers, symstore.exe, or John Robbins, get up to speed by reading John&#8217;s still-relevant 2002 Bugslayer article [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I &quot;released&quot; the <a href="http://www.aaronlerch.com/blog/2007/09/01/symbol-server-transaction-manager/">Symbol Server Transaction Manager</a>. It was a binaries-only, quick-and-dirty GUI wrapper utility I wrote on top of the symstore.exe command-line tool, at the prompting of <a href="http://www.wintellect.com/cs/blogs/jrobbins/default.aspx">John Robbins</a>. If you&#8217;re not familiar with Symbol Servers, <a href="http://msdn2.microsoft.com/en-us/library/ms681417(VS.85).aspx">symstore.exe</a>, or John Robbins, get up to speed by reading John&#8217;s <a href="http://msdn.microsoft.com/msdnmag/issues/02/06/Bugslayer/">still-relevant 2002 Bugslayer article</a> in MSDN magazine, or taking his <a href="http://wintellect.com/CourseDetail.aspx?Course=30">Mastering .NET Debugging</a> class.</p>
<p>I got some good feedback on the utility, along with some additional feature requests that ran outside the bounds of what the symstore utility offered. That lead me to upgrade my project to include a full-fledged (well, almost) symstore <em>replacement</em>, plus the GUI manager utility.</p>
<p>I&#8217;ve published the project tonight on CodePlex as &quot;<a href="http://www.codeplex.com/PSSymbolStore">PSSymbolStore</a>&quot;, and I&#8217;ve released the initial 0.1 beta release.</p>
<p>So what did I add and what did I change?</p>
<h5>PowerShell</h5>
<p>PSSymbolStore is now founded on a set of PowerShell cmdlets that replace and extend symstore&#8217;s functionality. (<em>Almost</em>: I need some feedback about a few symstore features and how they might work in the PowerShell world. If you&#8217;re a symstore wizard &#8211; ahem, John &#8211; <a href="mailto:aaronlerch@gmail.com">drop me a line</a>.) The initial release includes the following cmdlets, along with full help, including examples:</p>
<ul>
<li><b>Add-Symbols</b> &#8211; Adds symbols to the symbol store </li>
<li><b>Get-Transaction</b> &#8211; Retrieves some or all of the transactions from a symbol store </li>
<li><b>Remove-Transaction</b> &#8211; Deletes transaction(s) from a symbol store </li>
<li><b>Lock-Transaction</b> &#8211; Locks transaction(s), preventing them from being deleted with the Remove-Transaction cmdlet </li>
<li><b>Unlock-Transaction</b> &#8211; Unlocks transaction(s), allowing them to be deleted with the Remove-Transaction cmdlet </li>
</ul>
<h5>Symbol Store Manager</h5>
<p>The Symbol Store Manager (formerly &quot;Symbol Server Transaction Manager&quot;) is basically the same from a UI perspective, but has been massively gutted. The internal changes (MVP pattern, PowerShell hosting, etc.) are all for the better as they fully enable unit testing, which is coming in a future release. I&#8217;m looking for feedback on the UI &#8211; what I can improve, etc. It&#8217;s really basic right now. I had started adding a search feature using <a href="http://www.shuffletext.com/Highlight/Default.aspx">ShuffleText&#8217;s Highlight</a> fuzzy search library, but didn&#8217;t have time to finish it the way I wanted so I&#8217;ve pushed it out to a future release.</p>
<p><a href="http://www.aaronlerch.com/files/blog/SymbolStoreManageropensourceandabetarele_13996/SymbolStoreManager.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="302" alt="Symbol Store Manager" src="http://aaronlerch.com.s3.amazonaws.com/images/SymbolStoreManager_thumb.png" width="500" border="0" /></a> </p>
<h5>vNext</h5>
<p>So what&#8217;s coming next? I&#8217;ve already mentioned unit tests and searching. I&#8217;m also kicking around some UI enhancements. Aside from those features, and finishing up some &quot;paperwork&quot; like installs, I don&#8217;t currently have a strong feature list. If you have ideas, please either post them as a comment here, or even better on the <a href="http://www.codeplex.com/PSSymbolStore">codeplex project site</a>. For example: would this be more useful as an MMC snap-in instead of a standalone application?</p>
<p><a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx">Download PowerShell</a> if you haven&#8217;t already, and give <a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=PSSymbolStore&amp;ReleaseId=9441">PSSymbolStore 0.1 Beta</a> a whirl &#8211; I hope it&#8217;s useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2007/12/30/symbol-store-manager-open-source-and-a-beta-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Loading &#8220;collocated&#8221; file dependencies at runtime</title>
		<link>http://www.aaronlerch.com/blog/2007/12/12/loading-collocated-file-dependencies-at-runtime/</link>
		<comments>http://www.aaronlerch.com/blog/2007/12/12/loading-collocated-file-dependencies-at-runtime/#comments</comments>
		<pubDate>Wed, 12 Dec 2007 04:42:46 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2007/12/12/loading-collocated-file-dependencies-at-runtime/</guid>
		<description><![CDATA[Best quote this year, from an internal email thread this morning: ‘Just Say No’ to collocated file dependencies at run time. Loading file dependencies (like images, etc.) at runtime in a dynamic way can be tricky without resorting to a global information store like the registry. How do you know where your .NET application is [...]]]></description>
			<content:encoded><![CDATA[<p>Best quote this year, from an internal email thread this morning:</p>
<blockquote><p>‘Just Say No’ to collocated file dependencies at run time.</p></blockquote>
<p>Loading file dependencies (like images, etc.) at runtime in a dynamic way can be tricky without resorting to a global information store like the registry. How do you know where your .NET application is &#8220;executing from&#8221;? You could be loaded via COM into another process, loaded into a .NET application via custom assembly resolution code, or shadow-copied in an ASP.NET application. If you&#8217;re depending on collocated files, where should you get them from? Of course this depends on your install strategy and any policy your architecture defines.</p>
<p>Here&#8217;s a summary of the different ways you can retrieve a path (whether &#8220;C:\foo&#8221; or &#8220;http://www.foo.com/&#8221;) representing an assembly&#8217;s &#8220;location&#8221;. All this information is available on MSDN, I&#8217;m just compiling it together here. Nothing original here! Move along&#8230;</p>
<p>Actually, the <em>first</em> question is &#8220;which assembly&#8221;?</p>
<blockquote><p><strong>1. </strong><a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.getassembly.aspx"><strong>Assembly.GetAssembly</strong></a> &#8211; Retrieves the loaded assembly that defines the specified type.<br />
<strong>2. </strong><a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.getcallingassembly.aspx"><strong>Assembly.GetCallingAssembly</strong></a> &#8211; Retrieves the assembly containing the first method up in the call stack. <strong>Big warning here:</strong> your current method can be expanded inline by the compiler and you might not get the results you expect. If you are going to call GetCallingAssembly and rely on particular results, mark your method with the <a href="http://msdn2.microsoft.com/en-us/library/system.runtime.compilerservices.methodimplattribute.aspx">[MethodImpl(MethodImplOptions.NoInlining)]</a> attribute. Scott Hanselman has a good <a href="http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx">write-up of the scenario</a>, and an important warning: don&#8217;t mess around with the MethodImplAttribute for no reason. Know what you&#8217;re doing.<br />
<strong>3. </strong><a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.getentryassembly.aspx"><strong>Assembly.GetEntryAssembly</strong></a> &#8211; The first executed assembly in the AppDomain. If you have a standard WinForms application called &#8220;Foobar&#8221;, it&#8217;ll be the Foobar.exe. If you&#8217;re in code that was loaded into another AppDomain but wasn&#8217;t executed, it&#8217;ll be null.<br />
<strong>4. </strong><a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.getexecutingassembly.aspx"><strong>Assembly.GetExecutingAssembly</strong></a> &#8211; Gets the assembly that contains the currently executing code. This is the safest way to say &#8220;my assembly&#8221;.</p></blockquote>
<p>Once you&#8217;re sure you&#8217;ve got the correct assembly, you can get it&#8217;s location.</p>
<blockquote><p><strong>1. </strong><a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.location.aspx"><strong>Assembly.Location</strong></a> &#8211; The location of the loaded file that contains the manifest (important note for the few of you who create <a href="http://msdn2.microsoft.com/en-us/library/226t7yxe.aspx">multi-file assemblies</a>&#8211;though <a href="http://blogs.msdn.com/junfeng/archive/2005/02/12/371683.aspx">here&#8217;s some reasons</a> why you&#8217;d want to). If it was shadow-copied, it&#8217;s the post-copy location. If it was loaded from a byte array (like <a href="http://www.aisto.com/roeder/dotnet/">Reflector</a> does &#8211; seriously, have you ever &#8220;reflector&#8217;d&#8221; over Reflector? <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) then it&#8217;ll return an empty string.<br />
<strong>2. </strong><a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.codebase.aspx"><strong>Assembly.CodeBase</strong></a> &#8211; The originally specified location of the assembly. For example, if you load &#8220;C:\Foo.dll&#8221; this property will return file:///C:/Foo.dll.<br />
<strong>3. </strong><a href="http://msdn2.microsoft.com/en-us/library/system.appdomain.basedirectory.aspx"><strong>AppDomain.BaseDirectory</strong></a> &#8211; &#8220;The base directory the assembly resolver uses to probe for assemblies.&#8221; In PowerShell, for example, this returns &#8220;C:\WINDOWS\system32\WindowsPowerShell\v1.0\&#8221;.<br />
<strong>4. </strong><a href="http://msdn2.microsoft.com/en-us/library/system.reflection.module.fullyqualifiedname.aspx"><strong>Module.FullyQualifiedName</strong></a> &#8211; The location of a particular module in an assembly. Using PowerShell again&#8211;the best .NET playground around:<br />
PS C:\&gt; [System.Reflection.Assembly]::GetExecutingAssembly().GetModules()[0].FullyQualifiedName<br />
C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll<br />
<strong>5. Update:</strong> Jeffrey Palermo <a href="http://codebetter.com/blogs/jeffrey.palermo/archive/2008/01/10/reading-in-config-files-one-way-what-s-the-path.aspx">has one more to add</a>: <a href="http://msdn2.microsoft.com/en-us/library/system.appdomain.setupinformation.aspx">AppDomain.CurrentDomain.SetupInformation.ApplicationBase</a>.</p></blockquote>
<p>Of course, if the &#8220;collocated file&#8221; you&#8217;re trying to load is an <a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.aspx">Assembly</a>, the best choice is to use the built-in assembly resolution via <a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.load.aspx">Assembly.Load</a> &#8211; it <a href="http://msdn2.microsoft.com/en-us/library/yx7xezcf%28VS.71%29.aspx">takes into account</a> configuration file redirects, publisher policy, GAC vs. private, and well-defined probing rules. My non-official rule of thumb: always always always try to avoid loading assemblies manually.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2007/12/12/loading-collocated-file-dependencies-at-runtime/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

