<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.irm.se/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Eric's Blog</title><link>http://blog.irm.se/blogs/eric/default.aspx</link><description>Day to day experience in .NET</description><dc:language>en</dc:language><generator>CommunityServer 2.1 (Build: 60809.935)</generator><item><title>Information and Events are Stable Parts of Business</title><link>http://blog.irm.se/blogs/eric/archive/2012/01/13/Information-and-Events-are-Stable-Parts-of-Business.aspx</link><pubDate>Fri, 13 Jan 2012 09:32:51 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48793</guid><dc:creator>ericqu</dc:creator><slash:comments>1</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48793.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48793</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48793</wfw:comment><description>&lt;p&gt;&lt;img src="http://blog.irm.se/photos/eric/images/48792/original.aspx" /&gt;&lt;/p&gt;  &lt;p&gt;At IRM we often use this picture to talk about the stable parts of the business. Actually we have used it at least during the eight years I‘ve been working here.&lt;/p&gt;  &lt;p&gt;The least stable part is the &lt;strong&gt;organisation&lt;/strong&gt; itself. Many of us have been affected by organisational changes during the last year and just as many of us will be affected by a change this year. Since it changes all the time it would be unwise to base any software architecture on the current organisation.     &lt;br /&gt;As a side note: This is one reason to why I often talk about (user) roles as a bad thing to base the security checks on for a system, even though it is often well supported by the platform.&lt;/p&gt;  &lt;p&gt;The most stable part of the business is the structure of the &lt;strong&gt;information&lt;/strong&gt; we need. As long as IRM have been a consultancy firm we have provided &lt;em&gt;services &lt;/em&gt;to our &lt;em&gt;customers&lt;/em&gt; in &lt;em&gt;projects &lt;/em&gt;for which we have always tracked the hours (&lt;em&gt;time&lt;/em&gt;) each &lt;em&gt;employee&lt;/em&gt; have worked. Surely the information changes too, for example we have for many years educated other in both internal and open &lt;em&gt;courses&lt;/em&gt;, but this was not part of the business when IRM started back in 1982. The content changes (hopefully) rapidly with new customers and projects all the time, but not what information we need to track. &lt;/p&gt;  &lt;p&gt;How we have performed our services and the internal work have changed over time. It is the &lt;strong&gt;process&lt;/strong&gt; we try to improve all the time. Since the process itself is something that we want to change this is also unwise to base the software architecture on. Still this was a very common advise when SOA was hitting the hype curve, but I believe that is a mistake that happened because we so eagerly wanted to align our solutions better to the business process (of course the system need to support the processes very well, but it shouldn’t be the part that we base our architecture on).     &lt;br /&gt;If we dig a little bit deeper into processes they are a series of &lt;u&gt;activities&lt;/u&gt;, triggered by an &lt;u&gt;event&lt;/u&gt;, that are performed to deliver a &lt;u&gt;value&lt;/u&gt; for a &lt;u&gt;customer&lt;/u&gt;. The activities are more stable than the process itself, but even more stable are the events. Actually there is an event after each activity that triggers the next activity. An event can also be found when studying the state transitions of the information, for example visualized in an UML State Diagram. This have lead me to talk about the events as the line between Process and Information in the stability diagram above.&lt;/p&gt;  &lt;p&gt;I would say that information and events are two important artifacts to pay special attention to when designing software. This spans from defining the correct aggregates (in DDD) to defining service boundary (in SOA) or Bounded Context (in DDD) to integration between systems. I haven’t written about business capabilities in this post, but also when using capabilities for example to define services, you need to make sure that information which must be consistent (not eventually consistent) belongs to the same capability and the most important way of communication between services are based on events.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48793" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Event+Sourcing/default.aspx">Event Sourcing</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/CQRS/default.aspx">CQRS</category></item><item><title>Deploying ClickOnce to Multiple Environments</title><link>http://blog.irm.se/blogs/eric/archive/2011/09/14/Deploying-ClickOnce-to-Multiple-Environments.aspx</link><pubDate>Wed, 14 Sep 2011 13:05:20 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48779</guid><dc:creator>ericqu</dc:creator><slash:comments>2</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48779.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48779</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48779</wfw:comment><description>&lt;p&gt;So in my struggling to get a lean and effective way to roll out new versions of an application for two of my clients, I have some more to share with you. I want it to be extremely easy for me to create a new ClickOnce installer for my clients and I have identified three things that I need to solve:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The installations will be run from different installation URL:s.&lt;/li&gt;    &lt;li&gt;Getting unique config-files packed with the ClickOnce publish. I have 2 clients, each with a test and a production environment, and I need to handle my own test environment too.&lt;/li&gt;    &lt;li&gt;A client machine needs to be able to run installations for both test and production on a single machine. This means that ClickOnce must see my applications as different applications even though it is only one.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I have solved the last two, so lets start with the last one.&lt;/p&gt;  &lt;h4&gt;Running both test and production environments on the same client&lt;/h4&gt;  &lt;p&gt;There are more than one way to solve this, but for me the easiest solution was to create two Visual Studio projects. Originally I had a single Windows Forms exe project in Visual Studio, but I changed this to be just a DLL-project (Output type in Application settings). Then I created two new projects with the names Application and Application.Test and for both of them I configured ClickOnce as usual. There is only a single line of code in each of these projects and that’s to call the original entry point in my old exe-project:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;Program&lt;/span&gt;.Main(args);&lt;/pre&gt;

&lt;p&gt;With this solved I still needed to handle the differences in configurations.&lt;/p&gt;

&lt;h4&gt;Different config for each environment&lt;/h4&gt;

&lt;p&gt;Visual Studio 2010 has support for transforming configuration files when deploying a web project, but only when deploying and that is only supported for web projects. &lt;a href="http://sedodream.com/2011/08/17/AppconfigTransformVisualStudioAddIn.aspx"&gt;Luckily Sayed Ibrahim Hashimi and Chuck England have created a small VSiX&lt;/a&gt; called &lt;a href="http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5"&gt;SlowCheetah XML Transforms&lt;/a&gt; that do the same thing, but when you build your project. So naturally the first step is to install the add-in. Next up is to create new project configurations in configuration manager (I created CustomerATest, CustomerAProd, CustomerBTest and CustomerBTest). With this in place you can right-click on the config-file in you project and select Add Transform, which adds a sub-config file for each configuration. In these config files you then &lt;a href="http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx"&gt;apply the transformations for the changes you want to do&lt;/a&gt; in the config file.&lt;/p&gt;

&lt;p&gt;This is so useful in many more scenarios than just for deploying with ClickOnce.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Unfortunately I haven’t solved the problem of having different installation URL:s for each configuration, but maybe someone has a tip? I have tried to edit the project file and move the installation url element to respective configuration. This works if I remember to reload the project each time I select another configuration (which I of course don’t), but if I don’t reload the settings will be overwritten with the value from the configuration that was used when the project was loaded so that won’t work. The best thing would of course be if Visual Studio could start to support different installation URL for each configuration.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48779" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/Windows+Forms/default.aspx">Windows Forms</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>ClickOnce to the Rescue</title><link>http://blog.irm.se/blogs/eric/archive/2011/08/23/ClickOnce-to-the-Rescue.aspx</link><pubDate>Tue, 23 Aug 2011 13:58:25 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48770</guid><dc:creator>ericqu</dc:creator><slash:comments>0</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48770.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48770</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48770</wfw:comment><description>&lt;p&gt;I have two clients who are outsourcing their PCs and servers and one consequence of that is from now on it will take 3 weeks (plus additional costs) to get a MSI delivered to the clients. This way to far from our fast deliveries that we have today, so I recommended them that we should move on to ClickOnce for distributing the application. This will allow us to roll out new versions quickly and keep the cost down to a minimum. &lt;/p&gt;  &lt;p&gt;There is a switchboard integrated though and I was a little bit uncertain if we could handle the requirements of the switchboard to start the client with arguments and always with a single instance of the application. It turned out to be really simple. First of all, we did not need to make any changes in our single instance code (which uses named pipes to communicate from second instance to first). &lt;/p&gt;  &lt;p&gt;When someone calls to my client, the switchboard makes a lookup by calling a web service. In the answer it retrieves the path to the installed client, including the correct command line arguments that should be used to start the application. When switching to a ClickOnce distribution the service are not able to include a local path anymore, since the server has no idea where the application is installed. After a quick search I found that ClickOnce can also be called with parameters so that was the path I choose to go down and it worked really well. This is what I needed to do:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;In the “Manifests” settings (found under “Publish Options”) it is required to check “Allow URL parameters to be passed to application”. &lt;/li&gt;    &lt;li&gt;Next I changed the web service so it returned the URL to the ClickOnce installation (not the bootstrapper exe, but the .application file which also needs to be the installation source) followed by regular query string parameters. &lt;/li&gt;    &lt;li&gt;In my code, I just added a small function that takes command line parameters (so I continue to support local installs) as in parameters and the returns them or the parameters send through the query string.      &lt;br /&gt;      &lt;br /&gt;      &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private static string&lt;/span&gt;[] GetCommandLineArguments(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ApplicationDeployment&lt;/span&gt;.IsNetworkDeployed &amp;amp;&amp;amp; &lt;span style="color:#2b91af;"&gt;ApplicationDeployment&lt;/span&gt;.CurrentDeployment != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ApplicationDeployment&lt;/span&gt;.CurrentDeployment.ActivationUri != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;span style="color:blue;"&gt;
        &lt;/span&gt;{
            &lt;span style="color:blue;"&gt;string &lt;/span&gt;queryString = &lt;span style="color:#2b91af;"&gt;ApplicationDeployment&lt;/span&gt;.CurrentDeployment.ActivationUri.Query;
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!&lt;span style="color:blue;"&gt;string&lt;/span&gt;.IsNullOrEmpty(queryString))
            {
                queryString = queryString.Replace(&lt;span style="color:#a31515;"&gt;'?'&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;'/'&lt;/span&gt;).Replace(&lt;span style="color:#a31515;"&gt;'='&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;':'&lt;/span&gt;);
                &lt;span style="color:blue;"&gt;return &lt;/span&gt;queryString.Split(&lt;span style="color:#a31515;"&gt;'&amp;amp;'&lt;/span&gt;);
            }
        }
    }

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;args;
}&lt;/pre&gt;
The ActivationUri will always be null if the “Allow URL parameters to be passed to application” isn’t set. &lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48770" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/Windows+Forms/default.aspx">Windows Forms</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>Hosting Rhino Service Bus in IIS</title><link>http://blog.irm.se/blogs/eric/archive/2011/06/19/Hosting-Rhino-Service-Bus-in-IIS.aspx</link><pubDate>Sun, 19 Jun 2011 20:08:00 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48756</guid><dc:creator>ericqu</dc:creator><slash:comments>5</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48756.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48756</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48756</wfw:comment><description>&lt;p&gt;This is my third post (&lt;a href="http://blog.irm.se/blogs/eric/archive/2011/06/18/Getting-Started-with-Pub_2F00_Sub-using-Rhino-Service-Bus.aspx"&gt;part 1&lt;/a&gt;, &lt;a href="http://blog.irm.se/blogs/eric/archive/2011/06/19/Consuming-Events-in-the-Same-Process-as-the-Publisher-with-Rhino-Service-Bus.aspx"&gt;part 2&lt;/a&gt;) with notes from my exploration of Rhino Service Bus and in this I will focus on how to set everything up for Pub/Sub when having IIS as a host. The first thing that must be done is to choose a strategy for where to do the initialization of the bus and other parts of the service/application. &lt;a href="http://blogs.msdn.com/b/wenlong/archive/2006/01/11/511514.aspx"&gt;Here is a good blog post&lt;/a&gt; covering the choices and for this sample I choose the AppInitialized because it supports other protocols than http and I don&amp;rsquo;t need to support any other hosts than IIS so I don&amp;rsquo;t need to cover that.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;AppInitialize()
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;host = &lt;span style="color:blue;"&gt;new &lt;/span&gt;DefaultHost();
    host.Start&amp;lt;Bootstrapper&amp;gt;();

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;consumerHost = &lt;span style="color:blue;"&gt;new &lt;/span&gt;DefaultHost();
    consumerHost.UseStandaloneCastleConfigurationFileName(&lt;span style="color:#a31515;"&gt;&amp;quot;Consumer.config&amp;quot;&lt;/span&gt;);
    consumerHost.Start&amp;lt;Bootstrapper&amp;gt;();
}&lt;/pre&gt;

&lt;p&gt;In this test I trigger the events from button clicks on a webpage, but except for that everything works as in the &lt;a href="http://blog.irm.se/blogs/eric/archive/2011/06/19/Consuming-Events-in-the-Same-Process-as-the-Publisher-with-Rhino-Service-Bus.aspx"&gt;previous post&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;When deploying it to a server with IIS installed on, I manually created the Rhino Queue folders (in my case Publisher.esent, Publisher_subscriptions.esent, Consumer.esent and Consumer_subscriptions.esent). For each folder I than gave modify permission to the account running the application pool (you will get a access denied exception if you don&amp;rsquo;t do this and giving Modify permission on the parent folder does not seem like a good idea).&lt;/p&gt;

&lt;p&gt;I haven&amp;rsquo;t been able to get a sample with RemoteAppDomainHost to work. It complains about not being able to find Rhino.ServiceBus assembly and I&amp;rsquo;m pretty sure it has to do with ASP.NET shadow copying of files. Has anyone got this working? Please leave a comment or link in that case. Thanks, Eric.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48756" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/CQRS/default.aspx">CQRS</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Rhino+Service+Bus/default.aspx">Rhino Service Bus</category></item><item><title>Consuming Events in the Same Process as the Publisher with Rhino Service Bus</title><link>http://blog.irm.se/blogs/eric/archive/2011/06/19/Consuming-Events-in-the-Same-Process-as-the-Publisher-with-Rhino-Service-Bus.aspx</link><pubDate>Sun, 19 Jun 2011 13:25:42 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48753</guid><dc:creator>ericqu</dc:creator><slash:comments>1</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48753.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48753</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48753</wfw:comment><description>&lt;p&gt;I recently blogged about &lt;a href="http://blog.irm.se/blogs/eric/archive/2011/06/18/Getting-Started-with-Pub_2F00_Sub-using-Rhino-Service-Bus.aspx"&gt;getting started with Rhino Service Bus for publishing and subscribing&lt;/a&gt; to events. If you did not read that post, I recommend you to do that before continuing since I will just outline my modifications in this post.&lt;/p&gt;  &lt;p&gt;My scenario is that I want to decouple things that happens when my server is getting a command. I would like to just save the parts that is core to my domain as a direct effect of the command, but other things like calling other external systems and creating a change history I would like to do later on and in its own transactions. For this I wanted to publish events from my domain and then have subscribers handling each and every scenario separately. I thought it wouldn’t be necessary to have a second process though, so in this post I will show you how both the publisher and the subscriber can exist in the same process.&lt;/p&gt;  &lt;p&gt;So based on the steps in my previous post, I copied the class that consumes my events (implementing the ConsumerOf&amp;lt;&amp;gt; interface) to the publisher project. Now I need to have a second service bus host in the Publisher project and that second host must have its own configuration file.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I created a new configuration file, but instead of classic app.config, I called it Consumer.config and I also set the “Copy to Output Directory” to “Copy if newer”. The configuration file is a little bit different than the previous, because the host don’t want the surrounding castle element.     &lt;br /&gt;      &lt;br /&gt;      &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515;"&gt;xml &lt;/span&gt;&lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facilities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facility &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;rhino.esb&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bus &lt;/span&gt;&lt;span style="color:red;"&gt;threadCount&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;numberOfRetries&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;5&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;endpoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;rhino.queues://localhost:31317/RSB_Consumer_In_Publisher&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;Consumer&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;messages&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;add
          &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;RSB.Events&lt;/span&gt;&amp;quot;
          &lt;span style="color:red;"&gt;endpoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;rhino.queues://localhost:31315/RSB_Publisher&lt;/span&gt;&amp;quot;
          &lt;span style="color:blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;messages&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facility&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facilities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;After starting the Publisher host, I also added code to start the in-process Consumer host. The big difference here, compared to the consumer described in my last post, is that I tell the host to use another config-file, by calling UseStandaloneCastleConfigurationFileName.
    &lt;br /&gt;

    &lt;br /&gt;

    &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;host = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DefaultHost&lt;/span&gt;();
    host.Start&amp;lt;&lt;span style="color:#2b91af;"&gt;Bootstrapper&lt;/span&gt;&amp;gt;();
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Started server publisher.&amp;quot;&lt;/span&gt;);

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;consumerHost = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DefaultHost&lt;/span&gt;();
    consumerHost.UseStandaloneCastleConfigurationFileName(&lt;span style="color:#a31515;"&gt;&amp;quot;Consumer.config&amp;quot;&lt;/span&gt;);
    consumerHost.Start&amp;lt;&lt;span style="color:#2b91af;"&gt;Bootstrapper&lt;/span&gt;&amp;gt;();
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Started server consumer.&amp;quot;&lt;/span&gt;);

    &lt;span style="color:#2b91af;"&gt;IServiceBus &lt;/span&gt;bus = host.Container.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;IServiceBus&lt;/span&gt;&amp;gt;();
    bus.Notify(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Event1&lt;/span&gt;());
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Published Event1.&amp;quot;&lt;/span&gt;);

    &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(2000);

    bus.Notify(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Event2&lt;/span&gt;());
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Published Event2.&amp;quot;&lt;/span&gt;);

    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
}&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Another option for hosting in process is to use the RemoteAppDomainHost, which I believe will run in the same process, but in another AppDomain. This would probably add some robustness to the solution. The difference when using that hosting option is that the Consumer.config file will need to be an ordinary config-file with configSection and the facilities element must be contained in a castle element. The code for bringing the host up is similar to the one above.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;consumerHost = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;RemoteAppDomainHost&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Bootstrapper&lt;/span&gt;));&lt;span style="color:green;"&gt;
&lt;/span&gt;consumerHost.Configuration(&lt;span style="color:#a31515;"&gt;&amp;quot;Consumer.config&amp;quot;&lt;/span&gt;);&lt;span style="color:green;"&gt;
&lt;/span&gt;consumerHost.Start();
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Started server consumer.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48753" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/CQRS/default.aspx">CQRS</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Rhino+Service+Bus/default.aspx">Rhino Service Bus</category></item><item><title>Getting Started with Pub/Sub using Rhino Service Bus</title><link>http://blog.irm.se/blogs/eric/archive/2011/06/18/Getting-Started-with-Pub_2F00_Sub-using-Rhino-Service-Bus.aspx</link><pubDate>Sat, 18 Jun 2011 12:09:01 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48752</guid><dc:creator>ericqu</dc:creator><slash:comments>3</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48752.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48752</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48752</wfw:comment><description>&lt;p&gt;I have a project where I want to start publishing events on the server and then have a consumer subscribing to these events and take action. First I took a quick look at &lt;a href="http://www.nservicebus.com/"&gt;nServiceBus&lt;/a&gt;, but I also thought that it would be interesting to see what else exists on the .NET platform. I found both &lt;a href="http://masstransit.pbworks.com/"&gt;Mass Transit&lt;/a&gt; and &lt;a href="http://hibernatingrhinos.com/open-source/rhino-service-bus"&gt;Rhino Service Bus&lt;/a&gt; (RSB). I decided that Rhino Service Bus might fit very well with this project since it has built-in support for Rhino Queues (of course) and it is still open source without restrictions. Rhino Queues is interesting because it is a xcopy deployment.&lt;/p&gt;  &lt;p&gt;This post is mainly about giving RSB a first run, so it will be very basic and more like a dump of my own progress.&lt;/p&gt;  &lt;p&gt;First I created a simple project for defining the events (messages) and it only contains two empty classes Event1 and Event2. It might be worth noting that there is no requirements on the classes, aka it is not necessary to implement any interfaces or mark them with any attributes.&lt;/p&gt;  &lt;p&gt;After this I created a Publisher and a Consumer project and in both projects I added a reference to the Events project and I used NuGet to add a reference to Rhino Service Bus. I began with the publisher:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Added an empty classes called BootStrapper which inherit from AbstractBootStrapper.&lt;/li&gt;    &lt;li&gt;Added an app.config     &lt;br /&gt;      &lt;br /&gt;      &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configSections&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;section &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;castle&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configSections&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;castle&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facilities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facility &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;rhino.esb&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bus &lt;/span&gt;&lt;span style="color:red;"&gt;threadCount&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;numberOfRetries&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;5&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;endpoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;rhino.queues://localhost:31315/RSB_Publisher&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;Publisher&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;messages&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facility&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facilities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;castle&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;

&lt;/span&gt;&lt;/pre&gt;
    The endpoint attribute of the bus element defines the queue this bus is listening to. The “rhino.queues” defines that Rhino Queues should be used, but RSB also supports MSMQ by using the “msmq” moniker instead.&lt;/li&gt;

  &lt;li&gt;All that is left now is to start the bus and publish the events. The code for this is straight forward and self explained.
    &lt;br /&gt;

    &lt;br /&gt;

    &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;host = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DefaultHost&lt;/span&gt;();
    host.Start&amp;lt;&lt;span style="color:#2b91af;"&gt;Bootstrapper&lt;/span&gt;&amp;gt;();

    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Starting server publisher.&amp;quot;&lt;/span&gt;);
    &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);

    &lt;span style="color:#2b91af;"&gt;IServiceBus &lt;/span&gt;bus = host.Container.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;IServiceBus&lt;/span&gt;&amp;gt;();
    bus.Notify(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Event1&lt;/span&gt;());
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Published Event1.&amp;quot;&lt;/span&gt;);


    &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(2000);

    bus.Notify(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Event2&lt;/span&gt;());
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Published Event2.&amp;quot;&lt;/span&gt;);

    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
}&lt;/pre&gt;
    The IServiceBus supports both Notify and Publish for publishing events. The difference is that the later requires at least one listener.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So with the Publisher wrapped up, lets do the same three steps, plus one additional for the Consumer.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Added an empty classes called BootStrapper which inherit from AbstractBootStrapper.&lt;/li&gt;

  &lt;li&gt;Added an app.config&lt;/li&gt;

  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configSections&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;section &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;castle&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configSections&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;castle&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facilities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facility &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;rhino.esb&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bus &lt;/span&gt;&lt;span style="color:red;"&gt;threadCount&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;numberOfRetries&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;5&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;endpoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;rhino.queues://localhost:31316/RSB_Consumer&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;Consumer&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;messages&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;add
          &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;RSB.Events&lt;/span&gt;&amp;quot;
          &lt;span style="color:red;"&gt;endpoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;rhino.queues://localhost:31315/RSB_Publisher&lt;/span&gt;&amp;quot;
          &lt;span style="color:blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;messages&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facility&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;facilities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;castle&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;

&lt;/span&gt;&lt;/pre&gt;
Again the endpoint attribute of the bus element defines the queue this bus is listening to. In the consumer’s configuration I also added the messages that I want to listen for and pointing it to the endpoint that is publishing these events, aka the Publisher above.

  &lt;li&gt;Before starting the bus I also need to create a classes that can handle the events when they get published. This is done by implementing the ConsumerOf&amp;lt;&amp;gt; interface.
    &lt;br /&gt;

    &lt;br /&gt;

    &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EventConsumer &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;ConsumerOf&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Event1&lt;/span&gt;&amp;gt;, &lt;span style="color:#2b91af;"&gt;ConsumerOf&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Event2&lt;/span&gt;&amp;gt;
{
    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Consume(&lt;span style="color:#2b91af;"&gt;Event1 &lt;/span&gt;message)
    {
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Received Event1&amp;quot;&lt;/span&gt;);
    }

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Consume(&lt;span style="color:#2b91af;"&gt;Event2 &lt;/span&gt;message)
    {
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Received Event2&amp;quot;&lt;/span&gt;);
    }
}&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;As for the Publisher the last step is to start the bus and when this is done it will automatically tell the Publisher which events the Consumer want to receive. 
    &lt;br /&gt;

    &lt;br /&gt;

    &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;host = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DefaultHost&lt;/span&gt;();
    host.Start&amp;lt;&lt;span style="color:#2b91af;"&gt;Bootstrapper&lt;/span&gt;&amp;gt;();

    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
}&lt;/pre&gt;
    

    &lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48752" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/CQRS/default.aspx">CQRS</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Rhino+Service+Bus/default.aspx">Rhino Service Bus</category></item><item><title>Learning about CQRS and Event Sourcing</title><link>http://blog.irm.se/blogs/eric/archive/2011/03/06/Learning-about-CQRS-and-Event-Sourcing.aspx</link><pubDate>Sun, 06 Mar 2011 21:27:00 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48733</guid><dc:creator>ericqu</dc:creator><slash:comments>3</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48733.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48733</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48733</wfw:comment><description>&lt;p&gt;In my struggle to use &lt;a href="http://en.wikipedia.org/wiki/Domain_driven_design"&gt;Domain-Driven Design&lt;/a&gt; (DDD) in better ways to get more value out of it and not ending up with &lt;a href="http://martinfowler.com/bliki/AnemicDomainModel.html"&gt;anemic models&lt;/a&gt;, I began reading about Command Query Responsibility Segregation (CQRS) and Event Sourcing. These are two patterns that fit very well with DDD and two of the most influent thinkers in this area is Greg Young and Udi Dahan. In this post I will simply list a couple of resources that I have found to be very useful, but first let&amp;rsquo;s start with some of the reasons why I believe this is so interesting:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;When combining CQRS and Event Sourcing you will have a built-in integration model. For me, this is huge, since when is the last time you build an application/system in isolation? The problem often is that the need for integration is not taken care of until late in the project and then we add something on top of what we created more common than not with an unsatisfied result.&lt;/li&gt;&lt;li&gt;CQRS offers great separation of concerns and removes the need for supporting reporting in the domain model.&lt;/li&gt;&lt;li&gt;The application/system is built with three relatively loose coupled parts (domain model, read model and user interface) that can be developed and evolved independently from each other.&lt;/li&gt;&lt;li&gt;We store all events generated by the system (Event Sourcing). I believe events will get more and more attention over the coming years (if not Event-Driven Architecture and BI has already put a lot of focus on it) and it opens for many interesting business scenarios.&lt;/li&gt;&lt;li&gt;It is bare bone. This can sound strange, but during the last years I have tried many new frameworks (for example different O/R mappers, WCF RIA Services and so on) without getting the &amp;ldquo;reward&amp;rdquo; I&amp;rsquo;ve been hoping for. In my lab project so far I have not used any frameworks, but I don&amp;rsquo;t believe that I &amp;lsquo;m writing more code. Rather I find my code becoming better in many ways (easier to read and maintain, better separation of concerns, faster and more).&lt;/li&gt;&lt;li&gt;It fits very well with both cloud and SOA.&lt;/li&gt;&lt;li&gt;Offers some really good way to do unit testing (or at least I have learned better ways to do it when learning about CQRS and Event Sourcing).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There are more reasons which is outlined in many of the following resources that I&amp;rsquo;ve found good to start with:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://skillsmatter.com/podcast/design-architecture/architectural-innovation-eventing-event-sourcing/"&gt;1 hour introductionary video by Greg Young covering both CQRS and Event Sourcing&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/udi-dahan-command-query-responsibility-segregation/"&gt;1 2/3 hours video by Udi Dahan focusing on CQRS.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.viddler.com/explore/GregYoung/videos/8/383.043/"&gt;6,5 hours video by Greg Young going into more depth.&lt;/a&gt; I recommend you to take the time to watch this even though it is long. It can also be &lt;a href="http://dl.dropbox.com/u/108121/CQRS.zip"&gt;downloaded&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://cqrs.wordpress.com/"&gt;http://cqrs.wordpress.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://codebetter.com/gregyoung/"&gt;Greg Young&amp;rsquo;s blog&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ncqrs.org/"&gt;nCQRS - .NET Open Source framework for CQRS and Event Sourcing&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://groups.google.com/group/dddcqrs/"&gt;The CQRS forum&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Of course &lt;a href="http://www.domaindrivendesign.org/books/evans_2003"&gt;Domain-Driven Design by Eric Evans&lt;/a&gt; is pre-requisite and &lt;a href="http://www.domaindrivendesign.org/books/nilsson_2006"&gt;Jimmy Nilsson&amp;rsquo;s Applying Domain-Driven Design and Patterns&lt;/a&gt; book is also a good read. &lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48733" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Cloud+computing/default.aspx">Cloud computing</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Event+Sourcing/default.aspx">Event Sourcing</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/DDD/default.aspx">DDD</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/CQRS/default.aspx">CQRS</category></item><item><title>The Small Things: Asynchronous WCF Calls Without Setting Up Service Reference</title><link>http://blog.irm.se/blogs/eric/archive/2011/01/29/The-Small-Things_3A00_-Asynchronous-WCF-Calls-Without-Setting-Up-Service-Reference.aspx</link><pubDate>Sat, 29 Jan 2011 12:49:01 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48727</guid><dc:creator>ericqu</dc:creator><slash:comments>2</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48727.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48727</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48727</wfw:comment><description>&lt;p&gt;When you are developing both the service and the client it can many times be good to not use the “Add Service Reference” in Visual Studio. Instead the service and data contracts can be defined in a shared class library. There can be many reasons for this, on popping up immediately is that such a solution removes the need to always update the service reference as the service contract evolves. A “showstopper” could be that when using the ChannelFactory to create the proxy there are no asynchronous methods there to call. Lets start with a small example.&lt;/p&gt;  &lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;ServiceContract&lt;/span&gt;(Name = &lt;span style="color:#a31515;"&gt;&amp;quot;ProjectService&amp;quot;&lt;/span&gt;, Namespace = &lt;span style="color:#2b91af;"&gt;Constants&lt;/span&gt;.Namespace)]
&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IProjectService
&lt;/span&gt;{
    [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;]
    &lt;span style="color:#2b91af;"&gt;ProjectDetails &lt;/span&gt;GetProjectById(&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;id);
}&lt;/pre&gt;

&lt;p&gt;This simple service interface could be used on the client with the help of ChannelFactory:&lt;/p&gt;

&lt;pre class="code"&gt;factory = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ChannelFactory&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IProjectService&lt;/span&gt;&amp;gt;(“*”); 
&lt;span style="color:#2b91af;"&gt;IProjectService &lt;/span&gt;proxy = factory.CreateChannel();&lt;/pre&gt;

&lt;p&gt;The problem now is that we most often should make the calls to services asynchronous so that the client is not blocked. What we need to do to solve this is the create a client interface that exposes the asynchronous methods. In this case it will look like this:&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;ServiceContract&lt;/span&gt;(Name = &lt;span style="color:#a31515;"&gt;&amp;quot;ProjectService&amp;quot;&lt;/span&gt;, Namespace = &lt;span style="color:#2b91af;"&gt;Constants&lt;/span&gt;.Namespace)]
&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IProjectServiceClient &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IProjectService
&lt;/span&gt;{
    [System.ServiceModel.&lt;span style="color:#2b91af;"&gt;OperationContractAttribute&lt;/span&gt;(AsyncPattern = &lt;span style="color:blue;"&gt;true&lt;/span&gt;, &lt;br /&gt;        Action = &lt;span style="color:#2b91af;"&gt;Constants&lt;/span&gt;.Namespace + &lt;span style="color:#a31515;"&gt;&amp;quot;ProjectService/GetProjectById&amp;quot;&lt;/span&gt;, &lt;br /&gt;        ReplyAction = &lt;span style="color:#2b91af;"&gt;Constants&lt;/span&gt;.Namespace + &lt;span style="color:#a31515;"&gt;&amp;quot;ProjectService/GetProjectByIdResponse&amp;quot;&lt;/span&gt;)]
    System.&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginGetProjectById(System.&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;id, System.&lt;span style="color:#2b91af;"&gt;AsyncCallback &lt;/span&gt;callback, &lt;span style="color:blue;"&gt;object &lt;/span&gt;asyncState);

    &lt;span style="color:#2b91af;"&gt;ProjectDetails &lt;/span&gt;EndGetProjectById(System.&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;result);
}&lt;/pre&gt;

&lt;p&gt;Now all we need to do is of course switch the IProjectService to IProjectServiceClient in the ChannelFactory code and the asynchronous methods will be available. Oh … and one last thing, don’t forget to also change IProjectService to IProjectServiceClient in you client config file.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48727" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/Windows+Forms/default.aspx">Windows Forms</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/The+Small+Things/default.aspx">The Small Things</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>Windows Phone 7: First Impressions</title><link>http://blog.irm.se/blogs/eric/archive/2011/01/11/Windows-Phone-7_3A00_-First-Impressions.aspx</link><pubDate>Tue, 11 Jan 2011 22:43:04 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48725</guid><dc:creator>ericqu</dc:creator><slash:comments>1</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48725.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48725</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48725</wfw:comment><description>&lt;p&gt;Disclaimer: I’m still on parental leave so I have not used the phone in my daily work yet. Also worth noting when reading is that I’m a developer on the Microsoft platform, but I‘ve used iPhone 3GS for the last 1,5 year, I have an iPad. Before the iPhone I’ve used Windows Mobile for several years, but I also have owned both Nokia and Ericsson phones. I have no personal experience with any Android phones.&lt;/p&gt;  &lt;p&gt;I have now used my &lt;a href="http://www.google.se/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CCgQFjAA&amp;amp;url=http%3A%2F%2Fwww.engadget.com%2F2010%2F10%2F22%2Flg-optimus-7-review%2F&amp;amp;ei=N8gsTZjvD9HpObKgoL4K&amp;amp;usg=AFQjCNHzKMU_8ZqxdxgNmyfro60L35Cwvw"&gt;LG Optimus 7&lt;/a&gt; (LG-E900) &lt;a href="http://www.microsoft.com/windowsphone/en-us/default.aspx"&gt;Windows Phone 7&lt;/a&gt; (&lt;a title="http://en.wikipedia.org/wiki/Windows_Phone_7" href="http://en.wikipedia.org/wiki/Windows_Phone_7"&gt;http://en.wikipedia.org/wiki/Windows_Phone_7&lt;/a&gt;) for about three weeks. I did a reset of the phone after one week to start it up with a British Windows Live ID so that I could start using Marketplace since that is not available in Sweden yet. This touches on one of my biggest complains on the phone so far. It is very frustrating to buy a phone that is made available in Sweden, but without support for Marketplace and Xbox Live. Marketplace is crucial to get apps which is a must for a smartphone today and Xbox Live integration is one of the unique selling points of Windows Phone. My second biggest issue with the phone is the lack of support for Swedish, since that makes typing on the keyboard slow and error prone making it very hard to write any text even short messages/emails.&lt;/p&gt;  &lt;p&gt;With that put up front, let’s switch to some of the reasons that I have not returned to my iPhone, at least not yet. I spend less time in the phone and I love that because I still fulfill the same tasks as with my iPhone. The first thing that makes me more efficient is the start screen. By just turning the phone on, without unlocking it, I immediately sees my appointments, the number of emails on my different email accounts and the number of messages. Many times this is all I need to know. The Facebook integration (and Windows Live which is connected to LinkedIn) in the people hub also makes it easy, natural and fast to check what is happening. For the persons that I interact with the most, they are pinned to my Start so their status updates are even more available. It also makes it very easy to call my most common contacts, but this is comparable to the favorites in iPhone. The Live Tiles has a lot of potential and another nice use of them are in a Swedish application (TrafikTitt) which shows the traffic situation from one of the cameras covering the traffic situation in Stockholm. When covering the “performance” of the phone it is also worth noting that it feels very fast and smooth, but unfortunately that is not the same for installed apps, but hopefully the January update will address that. When talking about the first update, it is also worth mentioning that the Copy/Paste feature coming in that update is very much needed.&lt;/p&gt;  &lt;p&gt;The built in functionality is generally very good and easy to use. I like how the people hub integrated different source of information (Exchange, Hotmail, Facebook). The Exchange and Hotmail integration is way better than on iPhone and the mail functionality has some great features and are easy to use. Messaging is ok (haven’t used MMS though), but I would have liked to be able to delete parts of a conversation and not only an all or nothing. The calendar is ok, but I miss week view and the month view does not provide a good overview. Compared to iPhone, I’m glad that I can set Private-flag directly in the phone again. Internet Explorer have displayed all pages I’ve viewed so far correctly and the maps functionality works ok too. The pictures hub integrates pictures from my camera, computer and Facebook in a nice way, but the camera is poor when used indoors and when it is dark (as on most phones). I haven’t used the Mutlimedia or Office hub so much, but Zune seems to be a decent player and I really like how OneNote sync itself with SkyDrive and how I can pin OneNote notes to Start.&lt;/p&gt;  &lt;p&gt;I have only installed free applications from Marketplace so far and I will cover some of them here. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I really like the &lt;strong&gt;Facebook&lt;/strong&gt; application which is way better than on the iPhone. It uses the panorama in a good way and offers more functionality. &lt;/li&gt;    &lt;li&gt;For twitter I’ve used both the official &lt;strong&gt;Twitter&lt;/strong&gt; and &lt;strong&gt;Seesmic&lt;/strong&gt;, with the last one being my default one for the moment. It’s ok, but I like TweetDeck on the iPhone better. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Cocktail Flow&lt;/strong&gt; is a beautiful application and also provides some really nice features. This feels so much more fresh and compelling than the app I used on iPhone. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;TED&lt;/strong&gt; looks good and works very well. &lt;/li&gt;    &lt;li&gt;Microsoft &lt;strong&gt;Weather&lt;/strong&gt; app is ok, but way behind Klart.se app that I used on the iPhone. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;YouTube&lt;/strong&gt; is a must install to be able to watch YouTube content. I’ve installed two different where one just adds playing ability, but still uses YouTube mobile webpages to find content and another one with a custom interface for searching, and showing for example “most viewed”, “top rated” and so on. Only one of them integrates in the Multimedia hub though. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Adobe Reader &lt;/strong&gt;commonly needed for reading attachments. &lt;/li&gt;    &lt;li&gt;I have also installed some Swedish apps (for example &lt;a href="http://wp7applist.com/app/5701/TrafikTitt"&gt;TrafikTitt&lt;/a&gt;, Tågtid and STHML commute) which all seems nice, but I have only used them briefly. I look forward to the application showing results from the Swedish hockey league (Elitserien). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Overall it seems that there are momentum in Marketplace with more and more application becoming available. I have mentioned a couple of the ones I’m using above and I have also seen, but not used, &lt;a href="http://www.whsphone.com/"&gt;WHS Phone&lt;/a&gt; and &lt;a href="http://thesociablegeek.com/2011/01/06/wp7-minute-episode-vthe-kindle-app/"&gt;Kindle app&lt;/a&gt;.&amp;#160; What I miss most is “TV/radio players” for example for SVT Play and SR, Spotify (hope it integrates in the Mulitmedia hub), and site specific applications for example Hitta.se, Pricerunner, Prisjakt.se, Arla.se and others. In the car I sometimes miss TomTom which has served me well on the iPhone.&lt;/p&gt;  &lt;p&gt;The hardware on the different phones available in Sweden are comparable (as most of the phones available world wide) and the LG feels good even though not as designed as the iPhone. It has no extra on the hardware, except that I, just the other day, learned that it has &lt;a href="http://wmpoweruser.com/lg-optimus-7-also-has-gorilla-glass-that-makes-3/"&gt;gorilla glass&lt;/a&gt;. LG really shines on the software though. They have made a lot of apps available for free (Cocktail Flow is one of them) and that provides a lot of value so I’m very happy with my choice so far.    &lt;br /&gt;UPDATE 2011-01-12: I forgot to write that the battery life time seems to be comparable with other smart phones. The headset bundled with LG is way better than the one I got with my iPhone.&lt;/p&gt;  &lt;p&gt;To sum this up, I’m happy with the phone, but it has not unleashed its full potential yet. The apps needs to keep coming to Marketplace and core updates needs to be done by Microsoft (also after the January update). I would probably recommend most regular Swedish users to wait until Marketplace and Xbox Live is supported in Sweden and until Swedish language is supported.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48725" width="1" height="1"&gt;</description></item><item><title>Getting Started with Media Center Development in Visual Studio 2010</title><link>http://blog.irm.se/blogs/eric/archive/2010/12/07/Getting-Started-with-Media-Center-Development-in-Visual-Studio-2010.aspx</link><pubDate>Tue, 07 Dec 2010 22:08:00 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48723</guid><dc:creator>ericqu</dc:creator><slash:comments>3</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48723.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48723</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48723</wfw:comment><description>&lt;p&gt;I got an idea for an Windows Media Center (MCE)&amp;nbsp;application (add-in) that I wanted to try out if I could get it working. First step was to learn how to develop something for Media Center. I found this to be harder than I thought it would be, partly because I have chosen to not install Visual Studio 2008 on this machine. This post will be about the steps I needed to take to get a simple sample running in Media Center, including installation on another machine and the sample also working on the Xbox 360.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;First step was of course to install the Windows Media Center SDK, which could be found &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=542fc60e-f3c4-43a0-8dad-b8f14a485a74"&gt;here&lt;/a&gt;. Note that the link on &lt;a href="http://msdn.microsoft.com/en-us/library/bb895967.aspx"&gt;MSDN Windows Media Center Software Development Kit&lt;/a&gt; does not link to the latest version of the SDK download.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Since I don&amp;rsquo;t have Visual Studio 2008 installed the SDK does not install any project or file templates. Fortunately I found this blog &lt;a href="http://blog.retrosight.com/VeronicasRadioTimeDateAndWindowsMediaCenterSDKForWindows7Addendum.aspx"&gt;post&lt;/a&gt; by Charlie Owen, which all the way at the bottom has a link to &amp;ldquo;&lt;a href="http://blog.retrosight.com/ct.ashx?id=f5f59fb6-9bb5-4ed7-a8b0-d5a5dd3a68d2&amp;amp;url=http%3a%2f%2fretrosight.com%2fsamples%2fwindowsmediacentersdk%2f6%2fAddendum.zip"&gt;Windows Media Center SDK for Windows 7 Addendum&lt;/a&gt;&amp;rdquo;. That zip file contains the templates and the Readme has instructions on how to get them running in Visual Studio 2010.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;I choose the &amp;ldquo;Media Center Application&amp;rdquo; template for a new project and this creates a sample project almost ready to run. The project opens a Readme file with instruction about what is left to be done. I started out by fixing the two&amp;nbsp; first steps; &amp;ldquo;Create a strong name key file and add to the project assembly&amp;rdquo; and &amp;ldquo;Enter the strong name key in the registration file&amp;rdquo;. In the &amp;ldquo;Enter the strong name key &amp;hellip;&amp;rdquo; there are steps how to add a call to sn.exe in Visual Studio external tools, but since I only have VS2010 installed I also only have the latest Windows SDK so the path should be with v7.0A instead of v6.0A.     &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;My next step was to get the DevInstall.cmd going and the changes in there are also related to the fact that I only have version 7 of Windows SDK installed, but I also needed to fix it for running on 64-bit OS. What I did was to again replace v6.0A with v7.0A, but I also replaced the gac-variable in the path with the %ProgramFilesPath% since that is set correctly for 64-bit OS.     &lt;br /&gt;This allowed me to install the sample on my developing machine so that I could try it out in Media Center.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;I also wanted to get a setup up and running immediately so that I could try it out on my main Media Center machine which also has the Xbox 360 connected to itself. The template contains a WiX setup file and the Readme has instructions for you to install &lt;a href="http://wix.sourceforge.net/downloadv3.html"&gt;WiX 3&lt;/a&gt;, but I wanted to use &lt;a href="http://wix.sourceforge.net/downloadv35.html"&gt;WiX 3.5&lt;/a&gt; since I already had that installed. The changes required to get the setup running was as easy as changing the &amp;ldquo;WiX 3&amp;rdquo; part of the path in Build.cmd to &amp;ldquo;WiX 3.5&amp;rdquo;. Lastly I also removed the REM of the post build action call to Build.cmd and after building the project I had a setup file ready to test on my Media Center machine and everything worked as expected including running the sample on the Xbox.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Hope this helps if someone else wants to get started with Media Center Development in Visual Studio 2010.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48723" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Windows+Media+Center/default.aspx">Windows Media Center</category></item><item><title>The Small Things: Converting a Existing Web Application to a MVC Web Application</title><link>http://blog.irm.se/blogs/eric/archive/2010/11/24/The-Small-Things_3A00_-Converting-a-Existing-Web-Application-to-a-MVC-Web-Application.aspx</link><pubDate>Wed, 24 Nov 2010 09:54:00 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48721</guid><dc:creator>ericqu</dc:creator><slash:comments>1</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48721.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48721</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48721</wfw:comment><description>&lt;p&gt;I have an existing web application that contains a couple of WCF services, but today I also wanted to add some pages and decided that I wanted to create them with ASP.NET MVC2. This is the steps I took to get the MVC pages to run just fine in my existing application.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;First of all I added references to System.Web.Mvc and System.Web.Routing &lt;/li&gt;    &lt;li&gt;I created a dummy MVC project so that I could see what was missing in my existing project. &lt;/li&gt;    &lt;li&gt;Then I created the convention based folder structure. Except for the minimum required folders of Controllers and Views, I also added Scripts, Content and Model folders. &lt;/li&gt;    &lt;li&gt;I copied all the java script files from the dummy project to my Scripts folder. &lt;/li&gt;    &lt;li&gt;I added a Global.asax file to my project and copied the content from Global.asax in the dummy project, but of course corrected the default route. &lt;/li&gt;    &lt;li&gt;I opened up the dummy project file in Notepad, and the same with my existing project file. In the project files I looked for the &amp;lt;ProjectTypeGuids&amp;gt; and compared them. For ASP.NET MVC2 the {F85E285D-A4E0-4152-9332-AB1D724D3325} GUID was missing so I changed from:      &lt;ol&gt;       &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ProjectTypeGuids&amp;gt;{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}&amp;lt;/ProjectTypeGuids&amp;gt;          &lt;br /&gt;          &lt;br /&gt;to:&lt;/p&gt;        &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ProjectTypeGuids&amp;gt;&lt;font style="background-color:#ffff00;"&gt;{F85E285D-A4E0-4152-9332-AB1D724D3325};&lt;/font&gt;{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}&amp;lt;/ProjectTypeGuids&amp;gt;           &lt;br /&gt;&lt;/p&gt;        &lt;p&gt;Please note that the exact GUID will be different for ASP.NET MVC3 (I assume this anyway).&lt;/p&gt;     &lt;/ol&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;After doing this I also get the MVC file templates in the Add New Item dialog. I could continue without the MVC file templates, but this change removes a couple of manual steps of required changes that I otherwise would have needed to do in each added ASPX file based on the ordinary ASPX file template.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48721" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/The+Small+Things/default.aspx">The Small Things</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>Events and Multi-threaded Applications</title><link>http://blog.irm.se/blogs/eric/archive/2010/10/06/Events-and-Multi_2D00_threaded-Applications.aspx</link><pubDate>Wed, 06 Oct 2010 14:01:33 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48712</guid><dc:creator>ericqu</dc:creator><slash:comments>2</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48712.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48712</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48712</wfw:comment><description>&lt;p&gt;I had a problem lately where I sometimes got a NullReferenceException when raising an event. When searching for this problem I found plenty of information so this post is more a write up for myself :).&lt;/p&gt;  &lt;p&gt;The common way of implementing an event is something like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public event &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PropertyChangedEventHandler &lt;/span&gt;PropertyChanged;

&lt;span style="color:blue;"&gt;protected virtual void &lt;/span&gt;OnPropertyChanged(&lt;span style="color:#2b91af;"&gt;PropertyChangedEventArgs &lt;/span&gt;e)
{
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(PropertyChanged != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
        PropertyChanged(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, e);
}&lt;/pre&gt;

&lt;p&gt;This code works great in a single-threaded application, but when working with multiple threads we can get into problems. We have a risk of getting in a race condition where the subscriber to the event un-subscribes from the event between the null check and the call on the next line and that will cause a NullReferenceException. There are two ways to solve this problem; one is to assign an empty delegate to the event so it will never be null; the other one is to assign the event to a local variable before the null check like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;protected virtual void &lt;/span&gt;OnPropertyChanged(&lt;span style="color:#2b91af;"&gt;PropertyChangedEventArgs &lt;/span&gt;e)
{
    &lt;span style="color:#2b91af;"&gt;PropertyChangedEventHandler &lt;/span&gt;propertyChanged = PropertyChanged;
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(propertyChanged != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
        propertyChanged(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, e);
}&lt;/pre&gt;

&lt;p&gt;This effectively solves the NullReferenceException, but also raises the requirements for the consuming multi-threaded application because it is required to handle the fact that the subscribing code could be called even after un-subscribing to the event. Here is an example of changes that I would have needed to do in my consuming code to take this into condition. First the before code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;void &lt;/span&gt;currentProject_PropertyChanged(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, System.ComponentModel.&lt;span style="color:#2b91af;"&gt;PropertyChangedEventArgs &lt;/span&gt;e)
{
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(e.PropertyName.StartsWith(&lt;span style="color:#a31515;"&gt;&amp;quot;Enable&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase)) &lt;span style="color:blue;"&gt;return&lt;/span&gt;;

    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!modifiedProjects.Contains(CurrentProject))
    { 
        modifiedProjects.Add(CurrentProject);
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(modifiedProjects.Count == 1)
            OnPropertyChanged(() =&amp;gt; IsDirty);
    }
}&lt;/pre&gt;

&lt;p&gt;CurrentProject is a property in the class. Now to the changed code that would be correct even if receiving the event after un-subscribing to it:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;void &lt;/span&gt;currentProject_PropertyChanged(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, System.ComponentModel.&lt;span style="color:#2b91af;"&gt;PropertyChangedEventArgs &lt;/span&gt;e)
{
    &lt;span style="color:#2b91af;"&gt;ProjectViewModel &lt;/span&gt;project = (&lt;span style="color:#2b91af;"&gt;ProjectViewModel&lt;/span&gt;)sender;
            
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(e.PropertyName.StartsWith(&lt;span style="color:#a31515;"&gt;&amp;quot;Enable&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase)) &lt;span style="color:blue;"&gt;return&lt;/span&gt;;
    &lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;lock &lt;/span&gt;(modifiedProjectsLock)&lt;br /&gt;    {
&lt;br /&gt;        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!modifiedProjects.Contains(project))
        { 
           modifiedProjects.Add(project);
           &lt;span style="color:blue;"&gt;if &lt;/span&gt;(modifiedProjects.Count == 1)
               OnPropertyChanged(() =&amp;gt; IsDirty);
        }&lt;br /&gt;    }
}&lt;/pre&gt;

&lt;p&gt;Notice that I in this code uses the sender variable instead of just using the CurrentProject property. &lt;font color="#ff0000"&gt;UPDATE 2010-10-09:&lt;/font&gt;&lt;font color="#000000"&gt; Jeremy correctly commented that depending on scenario the modified property changed handler still had some synchronization bugs so I added a lock.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;In my case, I choose to assign an empty delegate to the event declaration because it solves the NullReferenceException without raising the bar for the consuming code. The drawback of this solution is a small performance hit, but that won’t be a real problem in most applications.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48712" width="1" height="1"&gt;</description></item><item><title>The Small Things: How to Show the Color Categories in Outlook</title><link>http://blog.irm.se/blogs/eric/archive/2010/08/11/The-Small-Things_3A00_-How-to-Show-the-Color-Categories-in-Outlook.aspx</link><pubDate>Wed, 11 Aug 2010 15:26:36 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48704</guid><dc:creator>ericqu</dc:creator><slash:comments>1</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48704.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48704</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48704</wfw:comment><description>&lt;p&gt;In an add-in for Outlook that I’m developing I wanted to show the built in Color Categories dialog so that the user could choose categories in a familiar way. The categories should be set on an object that is unique for the add-in (aka not for a mail or calendar item). I couldn’t find any way to show the dialog itself and when searching Internet I found nothing useful, but I have found an acceptable workaround. On the AppointmentItem (or one of the others) there is a method called ShowCategoriesDialog which shows the dialog, so what I did was to create a temporary appointment item, setting my categories, showing the dialog, read the Categories property and then finally cleaning up. Here is the code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;ShowAllCategories()
{
    Microsoft.Office.Interop.Outlook.&lt;span style="color:#2b91af;"&gt;Items &lt;/span&gt;items = IRM.TimeManager.Outlook.&lt;span style="color:#2b91af;"&gt;Globals&lt;/span&gt;.ThisAddIn.Calendar.Items;
    Microsoft.Office.Interop.Outlook.&lt;span style="color:#2b91af;"&gt;AppointmentItem &lt;/span&gt;item = (Microsoft.Office.Interop.Outlook.&lt;span style="color:#2b91af;"&gt;AppointmentItem&lt;/span&gt;)items.Add();

    &lt;span style="color:blue;"&gt;try
    &lt;/span&gt;{
        item.Categories = MyObject.Categories ?? &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Empty;
        item.ShowCategoriesDialog();
        MyObject.Categories = item.Categories;
    }
    &lt;span style="color:blue;"&gt;finally
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(item != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
        {
            item.Delete();
            System.Runtime.InteropServices.&lt;span style="color:#2b91af;"&gt;Marshal&lt;/span&gt;.FinalReleaseComObject(item);
        }
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(items != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            System.Runtime.InteropServices.&lt;span style="color:#2b91af;"&gt;Marshal&lt;/span&gt;.FinalReleaseComObject(items);
    }
}&lt;/pre&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48704" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/The+Small+Things/default.aspx">The Small Things</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/Office/default.aspx">Office</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>Programmatically Update a ClickOnce Distributed Office Add-in</title><link>http://blog.irm.se/blogs/eric/archive/2010/07/25/Programmatically-Update-a-ClickOnce-Distributed-Office-Add_2D00_in.aspx</link><pubDate>Sun, 25 Jul 2010 11:00:52 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48701</guid><dc:creator>ericqu</dc:creator><slash:comments>1</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48701.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48701</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48701</wfw:comment><description>&lt;p&gt;When using ClickOnce for distributing an Office Add-in the default configuration is to check for updates every 7 days. In an add-in I built I have situations where the add-in must be up to date (for example when changing the WCF service interface). In this post I will show how I solved it. &lt;/p&gt;  &lt;p&gt;To check for existing updates I use the regularly ClickOnce API:s, for example a simple check could look like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApplicationDeployment&lt;/span&gt;.IsNetworkDeployed &amp;amp;&amp;amp; &lt;span style="color:#2b91af;"&gt;ApplicationDeployment&lt;/span&gt;.CurrentDeployment.CheckForUpdate();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;If there is a new version available the solution is to quit Outlook and start another small updater program which will start the installation and then restart the application (Outlook in my case). I have called the little program OutlookRestarter and is a simple Windows Application which is created as its own project in the solution. The compiled output from that project, I have added to the add-in project as a linked file and the important part is to set the file as Content in the Build Action so that it will be included in the ClickOnce installation. 
  &lt;br /&gt;To start the OutlookRestarter I use a simple Process.Start and the only “hard” part about it is to resolve the folder in which the files are deployed:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;Uri &lt;/span&gt;updateLocation = &lt;span style="color:#2b91af;"&gt;ApplicationDeployment&lt;/span&gt;.CurrentDeployment.UpdateLocation;
                    
&lt;span style="color:#2b91af;"&gt;Assembly &lt;/span&gt;addinAssembly = &lt;span style="color:#2b91af;"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly();
&lt;span style="color:blue;"&gt;string &lt;/span&gt;cachePath = addinAssembly.CodeBase.Substring(0, addinAssembly.CodeBase.Length -
    System.IO.&lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.GetFileName(addinAssembly.CodeBase).Length);
&lt;span style="color:#2b91af;"&gt;Uri &lt;/span&gt;restarterPath = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Uri&lt;/span&gt;(cachePath + &lt;span style="color:#a31515;"&gt;&amp;quot;OutlookRestarter.exe&amp;quot;&lt;/span&gt;);

&lt;span style="color:#2b91af;"&gt;Process&lt;/span&gt;.Start(restarterPath.AbsoluteUri, updateLocation.AbsoluteUri.Replace(&lt;span style="color:#a31515;"&gt;&amp;quot;File.vsto&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Setup.exe&amp;quot;&lt;/span&gt;));

&lt;span style="color:#2b91af;"&gt;Globals&lt;/span&gt;.ThisAddIn.Application.Quit();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I pass the Url to the installation as an argument to OutlookRestarter and the only notable thing about it is that I replace vsto, with the bootstrapper exe file, because I get ClickOnce errors if trying to go for the vsto file directly.&lt;/p&gt;

&lt;p&gt;The OutlookRestarter application have three tasks; download the setup, run the setup and start Outlook again. I choose to download the file and run it manually to save the user from one click, which would be the effect if just doing a Process.Start on the Uri. For downloading the file I copied the DownloadFile method from &lt;a title="http://www.codeguru.com/columns/dotnettips/article.php/c7005" href="http://www.codeguru.com/columns/dotnettips/article.php/c7005"&gt;http://www.codeguru.com/columns/dotnettips/article.php/c7005&lt;/a&gt;, with a small modification. Before creating the file I check if it already exists and in that case deletes it. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:green;"&gt;//Download setup
&lt;/span&gt;&lt;span style="color:blue;"&gt;string &lt;/span&gt;tempFileName = &lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.Combine(&lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.GetTempPath(), &lt;span style="color:#a31515;"&gt;&amp;quot;Setup.exe&amp;quot;&lt;/span&gt;).ToString();
DownloadFile(args[0], tempFileName);

&lt;span style="color:green;"&gt;//Start and wait for setup to finish
&lt;/span&gt;System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Process &lt;/span&gt;setupProcess = System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Process&lt;/span&gt;.Start(tempFileName);
setupProcess.WaitForExit();&lt;span style="color:green;"&gt;

//Check to see if any existing Word Processes exist
&lt;/span&gt;System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Process&lt;/span&gt;[] currentOutlookProcesses =
    System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Process&lt;/span&gt;.GetProcessesByName(&lt;span style="color:#a31515;"&gt;&amp;quot;OUTLOOK&amp;quot;&lt;/span&gt;);

&lt;span style="color:green;"&gt;//Empty Case gets ignored, lazy but effective enough
&lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Process &lt;/span&gt;p &lt;span style="color:blue;"&gt;in &lt;/span&gt;currentOutlookProcesses) p.WaitForExit();

&lt;span style="color:green;"&gt;//Start Outlook
&lt;/span&gt;StartOutlook();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Before starting Outlook again I wait for setup to finish and also makes sure that Outlook is closed. To start Outlook I check the registry settings that is created by Office 2010 (14), but for Office 2007 (12) I make an assumption that it is installed under Program Files.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private static void &lt;/span&gt;StartOutlook()
{
    &lt;span style="color:green;"&gt;//Office 14 has installation path in the registry
    &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;RegistryKey &lt;/span&gt;localMachine = &lt;span style="color:#2b91af;"&gt;Registry&lt;/span&gt;.LocalMachine.OpenSubKey(&lt;span style="color:#a31515;"&gt;@&amp;quot;SOFTWARE\Microsoft\Office&amp;quot;&lt;/span&gt;);
    &lt;span style="color:blue;"&gt;object &lt;/span&gt;installationPath = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;
    &lt;span style="color:blue;"&gt;string &lt;/span&gt;installationFolder = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;

    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;string &lt;/span&gt;s &lt;span style="color:blue;"&gt;in &lt;/span&gt;localMachine.GetSubKeyNames())
    {
        installationPath = &lt;span style="color:#2b91af;"&gt;Registry&lt;/span&gt;.GetValue(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;@&amp;quot;{0}\{1}\{2}&amp;quot;&lt;/span&gt;, localMachine.ToString(), s, &lt;span style="color:#a31515;"&gt;@&amp;quot;Outlook\InstallRoot&amp;quot;&lt;/span&gt;), &lt;span style="color:#a31515;"&gt;&amp;quot;Path&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(installationPath != &lt;span style="color:blue;"&gt;null&lt;/span&gt;) &lt;span style="color:blue;"&gt;break&lt;/span&gt;;
    }

    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(installationPath != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
        installationFolder = installationPath.ToString();

    &lt;span style="color:green;"&gt;//Guess that Office is installed under Program Files
    &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(installationFolder == &lt;span style="color:blue;"&gt;null &lt;/span&gt;|| !&lt;span style="color:#2b91af;"&gt;File&lt;/span&gt;.Exists(&lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.Combine(installationFolder, &lt;span style="color:#a31515;"&gt;&amp;quot;Outlook.exe&amp;quot;&lt;/span&gt;))) &lt;span style="color:green;"&gt;//Office 12
    &lt;/span&gt;{
        installationFolder = &lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.Combine(System.&lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.GetFolderPath(&lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.&lt;span style="color:#2b91af;"&gt;SpecialFolder&lt;/span&gt;.ProgramFiles), &lt;span style="color:#a31515;"&gt;&amp;quot;Microsoft Office\\Office12&amp;quot;&lt;/span&gt;);
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!&lt;span style="color:#2b91af;"&gt;File&lt;/span&gt;.Exists(&lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.Combine(installationFolder, &lt;span style="color:#a31515;"&gt;&amp;quot;Outlook.exe&amp;quot;&lt;/span&gt;)))
            installationFolder = &lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.Combine(System.&lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.GetFolderPath(&lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.&lt;span style="color:#2b91af;"&gt;SpecialFolder&lt;/span&gt;.ProgramFilesX86), &lt;span style="color:#a31515;"&gt;&amp;quot;Microsoft Office\\Office12&amp;quot;&lt;/span&gt;);
    }

    &lt;span style="color:blue;"&gt;string &lt;/span&gt;filePath = &lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.Combine(installationFolder, &lt;span style="color:#a31515;"&gt;&amp;quot;Outlook.exe&amp;quot;&lt;/span&gt;);
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;File&lt;/span&gt;.Exists(filePath))
    {
        System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Process&lt;/span&gt;.Start(filePath);
    }
}&lt;/pre&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48701" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/Office/default.aspx">Office</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>Frustrating Hours With Report Web Viewer (v10 / VS 2010)</title><link>http://blog.irm.se/blogs/eric/archive/2010/05/19/Frustrating-Hours-With-Report-Web-Viewer-_2800_v10-_2F00_-VS-2010_2900_.aspx</link><pubDate>Wed, 19 May 2010 19:09:59 GMT</pubDate><guid isPermaLink="false">b9e303c5-a40c-4002-ae9b-d6aca1a9a983:48696</guid><dc:creator>ericqu</dc:creator><slash:comments>0</slash:comments><comments>http://blog.irm.se/blogs/eric/comments/48696.aspx</comments><wfw:commentRss>http://blog.irm.se/blogs/eric/commentrss.aspx?PostID=48696</wfw:commentRss><wfw:comment>http://blog.irm.se/blogs/eric/rsscomments.aspx?PostID=48696</wfw:comment><description>&lt;p&gt;I had some really frustrating hours with the new version of the Reporting Services Report Web Viewer today. We are using local reports, which we actually create dynamically (subject of another post), but we couldn’t get them to be showed by the Report Web Viewer. We started to seek the problem way off, because we of course assumed that the problem had to do with our creating of the report. Finally we took a step back and tried to get some really simple things to work, but with the same problem. The behavior was that the report viewer continuisly kept refreshing/posting for the report but never displaying it. After some searching I found this blog “&lt;a href="http://blogs.msdn.com/brianhartman/archive/2010/03/21/reports-never-stop-loading-with-vs-2010.aspx"&gt;Reports Never Stop Loading With VS 2010&lt;/a&gt;” and it turns out that the behavior of v9/VS2008 and v10/VS2010 is totally changed. The new version doesn’t use frames and HTTP handler anymore, but instead uses the AJAX support in ASP.NET. This means that the request for the report returns to the aspx page hosting the report viewer, but we did not check for IsPostback before initializing the viewer with the report and data which made us restart the process over and over again. Read the blog post above for details.&lt;/p&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48696" width="1" height="1"&gt;</description><category domain="http://blog.irm.se/blogs/eric/archive/tags/Reporting+Services/default.aspx">Reporting Services</category><category domain="http://blog.irm.se/blogs/eric/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item></channel></rss>
