<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Arun's blog</title><subtitle type="html" /><id>http://blogs.msdn.com/b/arkum/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/arkum/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/arkum/atom.aspx" /><generator uri="http://telligent.com" version="5.6.583.21163">Telligent Community 5.6.583.21163 (Build: 5.6.583.21163)</generator><updated>2008-10-22T08:10:00Z</updated><entry><title>Unit testing a CRM Plug-in</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/arkum/archive/2012/02/19/unit-testing-a-crm-plug-in.aspx" /><id>http://blogs.msdn.com/b/arkum/archive/2012/02/19/unit-testing-a-crm-plug-in.aspx</id><published>2012-02-19T05:24:00Z</published><updated>2012-02-19T05:24:00Z</updated><content type="html">&lt;p align="justify"&gt;As a TDD aficionado I never feel my code complete without writing unit tests. However you may not always be lucky to be working with a framework which has been designed with testability in mind, for e.g. ASP.NET MVC or WF4. CRM 2011’s plug-in programming model is definitely not one that belong to the “testable” category. This weekend I decided to venture out to see what it takes to unit test a a CRM plug-in.&lt;/p&gt;  &lt;p align="justify"&gt;CRM plug-ins are designed to be run inside the CRM server’s execution environment (mostly sandboxed) and often access CRM’s web services to create or retrieve entities. Hence it was clear that we have to use &lt;a href="http://xunitpatterns.com/Test%20Double.html"&gt;test doubles&lt;/a&gt; to make the plug-in run without the CRM environment. I decided to go with Moles framework from MSR (Microsoft Research), which can be downloaded for free. If you are not familiar with test doubles, I strongly recommend you read Martin Fowler’s concise and precise piece on it &lt;a href="http://martinfowler.com/bliki/TestDouble.html"&gt;here&lt;/a&gt; or take a look at the xunitpatterns.org website.&lt;/p&gt;  &lt;h2&gt;Download and Install Moles Framework&lt;/h2&gt;  &lt;p align="justify"&gt;Download and install Moles framework from &lt;a href="http://visualstudiogallery.msdn.microsoft.com/22c07bda-ffc9-479a-9766-bfd6ccacabd4"&gt;here&lt;/a&gt;. Remember to download x86 or x64 versions depending on your VS 2010 version.&lt;/p&gt;  &lt;h2&gt;CRM Plug-in&lt;/h2&gt;  &lt;p align="justify"&gt;The sample CRM plug-in shown in this blog leverages CRM 2011 developer toolkit. Though I strongly recommend it, it is in no way a pre-requisite for understanding how to unit-test a plug-in. Code below shows a very simple plug-in which validates the “telephone1” attribute of the account entity and throws an exception if the phone number is not a valid US phone number.&lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d3c30890-5e41-464e-b616-45237253b406" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;&lt;/div&gt; &lt;div style="background: #fff; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; ExecutePreValidateAccountCreate(&lt;span style="color:#2b91af"&gt;LocalPluginContext&lt;/span&gt; localContext)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (localContext == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;&amp;quot;localContext&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    }&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; account = localContext.PluginExecutionContext.InputParameters.ContainsKey(&lt;span style="color:#a31515"&gt;&amp;quot;Target&amp;quot;&lt;/span&gt;) ? &lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        localContext.PluginExecutionContext.InputParameters[&lt;span style="color:#a31515"&gt;&amp;quot;Target&amp;quot;&lt;/span&gt;] &lt;span style="color:#0000ff"&gt;as&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Entity&lt;/span&gt; : &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (account == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!account.Attributes.ContainsKey(&lt;span style="color:#a31515"&gt;&amp;quot;telephone1&amp;quot;&lt;/span&gt;)) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; phonenumber = account.Attributes[&lt;span style="color:#a31515"&gt;&amp;quot;telephone1&amp;quot;&lt;/span&gt;] &lt;span style="color:#0000ff"&gt;as&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(phonenumber)) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;    ValidatePhoneNumber(phonenumber);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; ValidatePhoneNumber(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; phoneNumber)&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#2b91af"&gt;Regex&lt;/span&gt; regexObj =    &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Regex&lt;/span&gt;(&lt;span style="color:#a31515"&gt;@&amp;quot;^&amp;#92;(?([0-9]{3})&amp;#92;)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!regexObj.IsMatch(phoneNumber))&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;InvalidPluginExecutionException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;&amp;quot;Invalid phone number&amp;quot;&lt;/span&gt; + phoneNumber);&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h2&gt;Unit test project&lt;/h2&gt;  &lt;p&gt;Add a test project to your CRM 2011 solution. Add a reference to Microsoft.Moles.Framework assembly&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-11-53-metablogapi/6518.image_5F00_6755A03F.png"&gt;&lt;img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-11-53-metablogapi/8156.image_5F00_thumb_5F00_0A55EBE3.png" width="568" height="263" /&gt;&amp;#160;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Add references to Microsoft.Xrm.Sdk and your plug-in assemblies to the test project.&lt;/p&gt;  &lt;h2&gt;Creating Unit test&lt;/h2&gt;  &lt;p align="justify"&gt;Let us start writing the unit test for the plug-in. The code in your unit test can be as simple as creating an object of your plug-in class and calling its Execute method. &lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3ddb0f4e-0e14-4b00-9152-6b49e7ccebf7" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Unit test&lt;/div&gt; &lt;div style="background: #fff; max-height: 200px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;[&lt;span style="color:#2b91af"&gt;TestClass&lt;/span&gt;]&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;PreValidateAccountCreateTest&lt;/span&gt;&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    [&lt;span style="color:#2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; TestPreValidateAccountCreate()&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    {&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p align="justify"&gt;However Execute method of the IPlugin Interface expects a parameter of type IServiceProvider from the System namespace in mscorlib assembly, a standard interface existed since .NET framework 1.0 days. IServiceProvider is nothing but a container (or dictionary) of services, indexed by the types of the contained services (or its abstract base classes/interfaces). When the plug-in is being executed by the CRM platform, CRM platform is responsible for creating the IServiceProvider object populated with services needed by the&amp;#160; plug-in and passing it to the Execute method. In a unit test method it is the responsibility of the author to provide all the dependencies required to run (test) the code being tested. Though you can manually create your own implementation of IServiceProvider and pass it to the Execute method, Moles framework comes handy here.&lt;/p&gt;  &lt;h2 align="justify"&gt;Creating Stubs&lt;/h2&gt;  &lt;p align="justify"&gt;Right-click the “References” node of your Test project to “Add moles assembly for mscorlib”. This action add a new file to your project “mscorlib.moles”. Compile your test project and you will see that a reference to mscorlib.Moles assembly has been added to your project automatically.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-11-53-metablogapi/6683.image_5F00_14C69A36.png"&gt;&lt;img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-11-53-metablogapi/3377.image_5F00_thumb_5F00_79ADCB27.png" width="396" height="221" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="justify"&gt;mscorlib.moles assembly contains stubs for various interfaces -including IServiceProvider- from the mscorlib assembly. What this means is you can re-write your boilerplate unit test code as shown below&lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e94879d7-f608-4673-850c-a8d1c8392ecf" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Unit test&lt;/div&gt; &lt;div style="background: #fff; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;[&lt;span style="color:#2b91af"&gt;TestClass&lt;/span&gt;]&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;PreValidateAccountCreateTest&lt;/span&gt;&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    [&lt;span style="color:#2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; TestPreValidateAccountCreate()&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; serviceprovider = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIServiceProvider&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; plugin = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;PreValidateAccountCreate&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;        plugin.Execute(serviceprovider);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    }&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p align="justify"&gt;Take a look at the &lt;span style="color: rgb(43, 145, 175);"&gt;SIServiceProvider&lt;/span&gt; class, which is present in the System.Moles namespace. The name of the class merits some decoding since it will help you understand the standard nomenclature moles framework uses. The class is named &lt;strong&gt;SIServiceProvider&lt;/strong&gt; because it is a “&lt;strong&gt;S&lt;/strong&gt;tub” for “&lt;strong&gt;IServiceProvider&lt;/strong&gt;” interface. Any stub class moles framework creates will be named as per this rule. This stub class, more than implementing the IServiceProvider interface, allows you to substitute methods and properties you are interested in (or your code -being tested-uses). &lt;/p&gt;  &lt;p align="justify"&gt;We have used the stub class for IServiceProvider in the above code, however it is not complete without stubbing the GetService method of IServiceProvider. Below is the temporary stub for the GetService method &lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9170e092-c670-4749-aac0-5f186384c6ba" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #fff; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;serviceprovider.GetServiceType = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Type&lt;/span&gt; type)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (type.Equals(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(IPluginExecutionContext)))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;; &lt;span style="color:#008000"&gt;//stub of pluginexecution context;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (type.Equals(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(IOrganizationServiceFactory)))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;span style="color:#008000"&gt;//stub of organization service factory;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;};&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p align="justify"&gt;when CRM platform executes a plug-in it expects the IServiceProvider container object to contain three objects of type ITracingService, IPluginExecutionContext and IOrganizationServiceFactory.&amp;#160; ITracingService is not mandatory if you are not doing any tracing, hence I have omitted the check in the GetService method stub.&lt;/p&gt;  &lt;p align="justify"&gt;As you guessed correctly, I am going to add stubs for IPluginExecutionContext and IOrganizationServiceFactory and they will be named as SIPluginExectuionContext and SIOrganizationServiceFactory. Since these interfaces are present in the Microsoft.Xrm.Sdk assembly, let us add&amp;#160; a mole file and create the stub classes. Right-click the Microsoft.Xrm.Sdk reference node and “Add Moles Assembly”.&amp;#160; &lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-11-53-metablogapi/8640.Add_2D00_reference_5F00_1ADDC104.png"&gt;&lt;img style="display: inline; background-image: none;" title="Add-reference" border="0" alt="Add-reference" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-11-53-metablogapi/3750.Add_2D00_reference_5F00_thumb_5F00_7356CECC.png" width="366" height="187" /&gt;&amp;#160;&lt;/a&gt;&lt;/p&gt;  &lt;p align="justify"&gt;This will add a new file called Microsoft.Xrm.Sdk.moles to the project. Build your test project, note that a new reference to “Microsoft.Xrm.Sdk.Moles” assembly is added automatically. This assembly contains stubs for interfaces explained earlier. The refactored unit test method using these stub classes should look like&amp;#160; &lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fed3a379-08fc-4aaf-975a-a5b7fc624cc0" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;&lt;/div&gt; &lt;div style="background: #fff; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;[&lt;span style="color:#2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; TestPreValidateAccountCreate()&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; serviceprovider = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIServiceProvider&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; pluginec = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIPluginExecutionContext&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; orgsf = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIOrganizationServiceFactory&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    serviceprovider.GetServiceType = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Type&lt;/span&gt; type)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (type.Equals(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(IPluginExecutionContext)))&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; pluginec;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (type.Equals(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(IOrganizationServiceFactory)))&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; orgsf;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;    };&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; plugin = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;PreValidateAccountCreate&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    plugin.Execute(serviceprovider);&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p align="justify"&gt;We have successfully stubbed the GetService method of the IServiceProvider interface. Similarly we have to stub out methods and properties of IPluginExecutionContext and IOrganizationServiceFactory.&lt;/p&gt;  &lt;p align="justify"&gt;Following code shows how we can stub IPluginExecutionContext interface.&lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0302292d-bf2a-4a65-a76a-36c9ce5f27ed" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;&lt;/div&gt; &lt;div style="background: #ddd; overflow: auto"&gt; &lt;ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; pluginec = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIPluginExecutionContext&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;pluginec.UserIdGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Guid&lt;/span&gt;(); };&lt;/li&gt; &lt;li&gt;pluginec.StageGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; 10; };&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;pluginec.MessageNameGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#a31515"&gt;&amp;quot;Create&amp;quot;&lt;/span&gt;; };&lt;/li&gt; &lt;li&gt;pluginec.PrimaryEntityNameGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#a31515"&gt;&amp;quot;account&amp;quot;&lt;/span&gt;; };&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; parametercollection = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ParameterCollection&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; accountentity = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Entity&lt;/span&gt;(&lt;span style="color:#a31515"&gt;&amp;quot;account&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;accountentity.Attributes.Add(&lt;span style="color:#a31515"&gt;&amp;quot;telephone1&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515"&gt;&amp;quot;123456&amp;quot;&lt;/span&gt;); ;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;parametercollection.Add(&lt;span style="color:#a31515"&gt;&amp;quot;Target&amp;quot;&lt;/span&gt;, accountentity);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;pluginec.InputParametersGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; parametercollection; };&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Line number 2-4 provides your own implementations of various properties because these are used in the constructor of your plug-in as shown below&lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b1c13266-6bfb-4ea9-a936-5cc645036161" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;&lt;/div&gt; &lt;div style="background: #fff; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;base&lt;/span&gt;.RegisteredEvents.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;int&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;LocalPluginContext&lt;/span&gt;&amp;gt;&amp;gt;(10, &lt;span style="color:#a31515"&gt;&amp;quot;Create&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515"&gt;&amp;quot;account&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;LocalPluginContext&lt;/span&gt;&amp;gt;(ExecutePreValidateAccountCreate)));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Lines 5-12 stubs properties as required by your plug-in code, especially InputParameters propery, “Target” indexer and “telephone1” attribute.&lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7bcc911d-049a-430e-bfb2-4391f037f551" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;&lt;/div&gt; &lt;div style="background: #fff; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; account = localContext.PluginExecutionContext.InputParameters.ContainsKey(&lt;span style="color:#a31515"&gt;&amp;quot;Target&amp;quot;&lt;/span&gt;) ? &lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    localContext.PluginExecutionContext.InputParameters[&lt;span style="color:#a31515"&gt;&amp;quot;Target&amp;quot;&lt;/span&gt;] &lt;span style="color:#0000ff"&gt;as&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Entity&lt;/span&gt; : &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (account == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!account.Attributes.ContainsKey(&lt;span style="color:#a31515"&gt;&amp;quot;telephone1&amp;quot;&lt;/span&gt;)) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; phonenumber = account.Attributes[&lt;span style="color:#a31515"&gt;&amp;quot;telephone1&amp;quot;&lt;/span&gt;] &lt;span style="color:#0000ff"&gt;as&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;;&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;It is time to provide a stub implementation for IOrganizationServiceFactory&lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c08857f0-8ffb-4a75-b75f-194f8f86190c" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;&lt;/div&gt; &lt;div style="background: #fff; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; orgservice = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIOrganizationService&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; orgsf = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIOrganizationServiceFactory&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;orgsf.CreateOrganizationServiceNullableOfGuid = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Guid&lt;/span&gt;? userid) { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; orgservice; };&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p align="justify"&gt;CRM uses IOrganizationServiceFactory interface’s CreateOrganizationService method to return an implementation of IOrganizationService interface. IOrgnizationService interface as well as CreaeOrganizatinService method are stubbed as shown in the above code sample.&lt;/p&gt;  &lt;p align="justify"&gt;It is time to run your test method. However, if you look at the phone number “12345”, you already know that your code is going to throw a InvalidPluginExecutionException. Add the ExpectedException attribute to your test method so that it knows what exception to expect. Your test method should like &lt;/p&gt;  &lt;div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fcdce4ef-0d3e-4b6e-b89b-5e672508cda4" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;&lt;/div&gt; &lt;div style="background: #fff; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"&gt; &lt;li&gt;[&lt;span style="color:#2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;[&lt;span style="color:#2b91af"&gt;ExpectedException&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;InvalidPluginExecutionException&lt;/span&gt;))]&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; TestPreValidateAccountCreate()&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; serviceprovider = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIServiceProvider&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; pluginec = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIPluginExecutionContext&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    pluginec.UserIdGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Guid&lt;/span&gt;(); };&lt;/li&gt; &lt;li&gt;    pluginec.StageGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; 10; };&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    pluginec.MessageNameGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#a31515"&gt;&amp;quot;Create&amp;quot;&lt;/span&gt;; };&lt;/li&gt; &lt;li&gt;    pluginec.PrimaryEntityNameGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#a31515"&gt;&amp;quot;account&amp;quot;&lt;/span&gt;; };&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; parametercollection = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ParameterCollection&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; accountentity = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Entity&lt;/span&gt;(&lt;span style="color:#a31515"&gt;&amp;quot;account&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;    accountentity.Attributes.Add(&lt;span style="color:#a31515"&gt;&amp;quot;telephone1&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515"&gt;&amp;quot;123456&amp;quot;&lt;/span&gt;); ;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    parametercollection.Add(&lt;span style="color:#a31515"&gt;&amp;quot;Target&amp;quot;&lt;/span&gt;, accountentity);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    pluginec.InputParametersGet = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;() { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; parametercollection; };&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; orgservice = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIOrganizationService&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; orgsf = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SIOrganizationServiceFactory&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;    orgsf.CreateOrganizationServiceNullableOfGuid = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Guid&lt;/span&gt;? userid) { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; orgservice; };&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    serviceprovider.GetServiceType = &lt;span style="color:#0000ff"&gt;delegate&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Type&lt;/span&gt; type)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (type.Equals(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(IPluginExecutionContext)))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; pluginec;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (type.Equals(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(IOrganizationServiceFactory)))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; orgsf;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    };&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; plugin = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;PreValidateAccountCreate&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;    plugin.Execute(serviceprovider);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Right-click your test method and run it inside visual studio. Observe the Test Results window to see whether it passed. You can add another test method with a valid US phone number to test the success code path of your plug-in. Alternately you can use Microsoft Pex for parameterizing your input values and create PUTs (Parameterized Unit Tests).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10269431" width="1" height="1"&gt;</content><author><name>arkum</name><uri>http://blogs.msdn.com/arkum/ProfileUrlRedirect.ashx</uri></author><category term="Unit testing" scheme="http://blogs.msdn.com/b/arkum/archive/tags/Unit+testing/" /><category term="CRM" scheme="http://blogs.msdn.com/b/arkum/archive/tags/CRM/" /><category term="Plug-in" scheme="http://blogs.msdn.com/b/arkum/archive/tags/Plug_2D00_in/" /><category term="Moles" scheme="http://blogs.msdn.com/b/arkum/archive/tags/Moles/" /></entry><entry><title>Multiparadigmatic .NET series from Ted Neward</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/arkum/archive/2011/03/27/multiparadigmatic-net-series-from-ted-neward.aspx" /><id>http://blogs.msdn.com/b/arkum/archive/2011/03/27/multiparadigmatic-net-series-from-ted-neward.aspx</id><published>2011-03-27T07:06:00Z</published><updated>2011-03-27T07:06:00Z</updated><content type="html">&lt;p&gt;1. &lt;a href="http://msdn.microsoft.com/en-us/magazine/ff955611.aspx"&gt;Part 1&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;2. &lt;a href="http://msdn.microsoft.com/en-us/magazine/gg232770.aspx"&gt;Part 2&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;3. &lt;a href="http://msdn.microsoft.com/en-us/magazine/gg309185.aspx"&gt;Part 3&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4. &lt;a href="http://msdn.microsoft.com/en-us/magazine/gg490357.aspx"&gt;Part 4&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;5. &lt;a href="http://msdn.microsoft.com/en-us/magazine/gg535677.aspx"&gt;Part 5&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;6. &lt;a href="http://msdn.microsoft.com/en-us/magazine/gg680287.aspx"&gt;Part 6&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10146327" width="1" height="1"&gt;</content><author><name>arkum</name><uri>http://blogs.msdn.com/arkum/ProfileUrlRedirect.ashx</uri></author><category term="Programming" scheme="http://blogs.msdn.com/b/arkum/archive/tags/Programming/" /></entry><entry><title>Getting really started with Mce</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/arkum/archive/2009/01/16/getting-really-started-with-mce.aspx" /><id>http://blogs.msdn.com/b/arkum/archive/2009/01/16/getting-really-started-with-mce.aspx</id><published>2009-01-16T09:23:40Z</published><updated>2009-01-16T09:23:40Z</updated><content type="html">&lt;p&gt;This post is long overdue. I was held up with activities on CCF 2009 SP1 release, which will be out shortly. Let us get started with installing Mce. &lt;/p&gt; &lt;h3&gt;Installing Mce&lt;/h3&gt; &lt;p&gt;Mce is a core component of CCF framework. You can choose to install Mce framework components by selecting the “MCE Components” option under Framework in CCF 2009 installer as shown below&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;a href="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_2.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="224" alt="image" src="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_thumb.png" width="325" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Mce software factory and DSLs are present under Developer Tools and Samples section in the installer as shown below&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;a href="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_4.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="235" alt="image" src="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_thumb_1.png" width="326" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Please note that you should have Guidance Automation Extension version 1.4 installed for using Mce Software Factory. You can download it from &lt;a title="http://www.microsoft.com/downloads/details.aspx?FamilyId=DF79C099-4753-4A59-91E3-5020D9714E4E&amp;amp;displaylang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=DF79C099-4753-4A59-91E3-5020D9714E4E&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=DF79C099-4753-4A59-91E3-5020D9714E4E&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_8.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" alt="image" src="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_thumb_3.png" width="331" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;h3&gt;Verifying Mce Installation&lt;/h3&gt; &lt;p&gt;Mce framework is nothing but a set of .NET assemblies and you can find these in the Framework directory under your CCF 2009 installation folder.&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_10.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="171" alt="image" src="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_thumb_4.png" width="473" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;To verify Mce software factory installation go to Add or Remove programs Applet in control panel and make sure you have the following components installed. If you have both Visual Studio 2005 and 2008 you will see Software Factory, WorkUnit and Logical View DSLs installed separately for 2005 and 2008.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_12.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="126" alt="image" src="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_thumb_5.png" width="472" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Make sure that there is new Solution type “MCE Solution” in the New Project dialog in Visual Studio under “Guidance Packages”&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_14.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="231" alt="image" src="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_thumb_6.png" width="390" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;After you create a Mce Solution you should see three menu options to create specific Mce project types.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_16.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="210" alt="image" src="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_thumb_7.png" width="403" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;In the Add new Item dialog you should see Item Templates corresponding to LogicalView and WorkUnit DSLs&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_18.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="235" alt="image" src="http://blogs.msdn.com/blogfiles/arkum/WindowsLiveWriter/GettingreallystartedwithMce_9915/image_thumb_8.png" width="440" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In the next post I will show you how to create your first multi-channel enabled application&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9324769" width="1" height="1"&gt;</content><author><name>arkum</name><uri>http://blogs.msdn.com/arkum/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Getting started with Mce</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/arkum/archive/2008/10/28/getting-started-with-mce.aspx" /><id>http://blogs.msdn.com/b/arkum/archive/2008/10/28/getting-started-with-mce.aspx</id><published>2008-10-28T21:07:50Z</published><updated>2008-10-28T21:07:50Z</updated><content type="html">&lt;h3&gt;&lt;font color="#0000ff"&gt;Understanding UI Process&lt;/font&gt;&lt;/h3&gt; &lt;p&gt;Before we delve into Mce let us try to dissect the term UI process. A UI process should have its controller logic, in our case it is going to be Windows Workflow. Since a controller interacts with the views as well, we need to hold a reference to the views participating in the UI-Process. Next is the data (a.k.a Model in MVC). Hang on, the UI process that we are talking here has to be reusable across channels, hence it cannot be holding references to the views it driving. &lt;/p&gt; &lt;p&gt;There are multiple ways of fixing this problem, the most common is using a set of fixed interface that every participating view has to implement and controller (Workflow) communicates to the view(s) through this interface. This looks fine when you are developing a fresh set of user interface elements. What if you would like to re-use some of the views&amp;nbsp; (for e.g. windows user controls, web user controls etc) from your existing application? Re-writing each view to implement the interface is not going to be that easy. Another approach is to write the controller logic against a set of UI abstractions. i.e. your controller logic will be written against a set of user interface abstractions instead of an interface or the views themselves, let us call this abstraction as a &lt;font color="#0000ff"&gt;&lt;strong&gt;Logical View&lt;/strong&gt;&lt;/font&gt;&lt;font color="#000000"&gt;. &lt;/font&gt;&lt;/p&gt; &lt;h3&gt;&lt;font color="#0000ff"&gt;WorkUnit&lt;/font&gt;&lt;/h3&gt; &lt;p&gt;A reusable UI process contains the controller logic + a set of logical views (against which controller logic is written) . This concept is abstracted as a WorkUnit in Mce. Hereafter I will not be using the term UI process a lot , instead you will see references to WorkUnit a lot. A WorkUnit in Mce represents a reusable navigation logic written using the Workflow foundation workflow and associated Logical Views. I deliberately omitted the discussion about data here, but we will come back to how data&amp;nbsp; is handled in a WorkUnit in Mce.&lt;/p&gt; &lt;h3&gt;&lt;font color="#0000ff"&gt;LogicalView&lt;/font&gt;&lt;/h3&gt; &lt;p&gt;As mentioned earlier, LogicalView is a channel independent abstraction of a Physical View (Windows form, Web User control, etc.). Hence a LogicalView contains properties (name and data type), events the view can raise and commands that you can perform on the view (or else functions that you can call on the view, if you have an instance of the view). &lt;/p&gt; &lt;h3&gt;&lt;font color="#0000ff"&gt;Navigational Event&lt;/font&gt;&lt;/h3&gt; &lt;p&gt;In Mce a Navigational Event represents channel independent abstraction of an event that the physical view will raise, for e.g. if the user clicks the next button in the physical view, you may want your controller to react a Navigational Event called "Next". In short you can write your controller logic against logical views and navigational events from those logical views.&lt;/p&gt; &lt;h3&gt;&lt;font color="#0000ff"&gt;Navigational Workflow&lt;/font&gt;&lt;/h3&gt; &lt;p&gt;Mce Navigational Workflow is the controller logic that you write using Windows Workflow foundation. You can write state machine or sequential workflows, state machines are the ones most commonly used.&lt;/p&gt; &lt;h3&gt;&lt;font color="#0000ff"&gt;Where is the Model?&lt;/font&gt;&lt;/h3&gt; &lt;p&gt;We talked about controller and views. How about model/data?. In Mce data that the controller interacts is actually represented as properties in the LogicalView itself. Hence the navigational workflow that you write is actually a controller + data/Model. This is done for the obvious reason of moving the controller logic across channels. When you move the controller logic from one channel to another you get the updated data values as well.&lt;/p&gt; &lt;p&gt;Enough of this diatribe, in my next post we will get our hands dirty with Mce in CCF 2009, and I will be covering more concepts and related terminologies as we proceed&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9020277" width="1" height="1"&gt;</content><author><name>arkum</name><uri>http://blogs.msdn.com/arkum/ProfileUrlRedirect.ashx</uri></author><category term="CCF" scheme="http://blogs.msdn.com/b/arkum/archive/tags/CCF/" /><category term="Mce" scheme="http://blogs.msdn.com/b/arkum/archive/tags/Mce/" /></entry><entry><title>Introducing CCF2009 and Mce</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/arkum/archive/2008/10/22/introducing-ccf2009-and-mce.aspx" /><id>http://blogs.msdn.com/b/arkum/archive/2008/10/22/introducing-ccf2009-and-mce.aspx</id><published>2008-10-22T10:10:00Z</published><updated>2008-10-22T10:10:00Z</updated><content type="html">&lt;H2 style="MARGIN: 10pt 0in 0pt"&gt;&lt;FONT face=Cambria color=#4f81bd size=4&gt;UI Process &lt;/FONT&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;Not a lot has been talked about UI Processes. You do a live search or google search for UI process and first result you get is Microsoft UI process application block. I tried Wikipedia for a standard definition without any luck. The only definition I could find is again from Microsoft UI Process application block tutorial which is &lt;/FONT&gt;&lt;/P&gt;
&lt;UL type=disc&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 2.25pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 140%; TEXT-ALIGN: justify; mso-margin-top-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;I&gt;&lt;SPAN style="FONT-SIZE: 8pt; COLOR: black; LINE-HEIGHT: 140%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;A user interface process&lt;/SPAN&gt;&lt;/I&gt;&lt;I style="mso-bidi-font-style: normal"&gt;&lt;SPAN style="FONT-SIZE: 8pt; COLOR: black; LINE-HEIGHT: 140%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt; — A set of user-related activities that achieve a goal. &lt;/SPAN&gt;&lt;/I&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;Microsoft UI Process Application block is the popular framework in .NET which allows you to implement UI Process functionalities in your application. But if you look at the server side counterpart (I mean, Business process orchestration) we have many standards products and frameworks ranging from BizTalk to many ESB frameworks. Lets see why it pays to care about UI Process as well&lt;/FONT&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 10pt 0in 0pt"&gt;&lt;FONT face=Cambria color=#4f81bd size=4&gt;MVC and UI Process&lt;/FONT&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;As the definition implies UI Process defines a navigational logic that you perform to achieve a goal (e.g. pay your Credit card bills online, Set archiving rules in outlook etc.). &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;To abstract away this navigational logic, we can use good old MVC pattern. Hence often when you talk about UI Processes you invariably end up talking about MVC and how you can centralize the controller logic&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;SPAN style="FONT-SIZE: 8pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-no-proof: yes"&gt;&lt;?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /&gt;&lt;v:shapetype id=_x0000_t75 stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"&gt;&lt;v:stroke joinstyle="miter"&gt;&lt;/v:stroke&gt;&lt;v:formulas&gt;&lt;v:f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 1 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum 0 0 @1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @2 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 0 1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @6 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @8 21600 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @10 21600 0"&gt;&lt;/v:f&gt;&lt;/v:formulas&gt;&lt;v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"&gt;&lt;/v:path&gt;&lt;o:lock aspectratio="t" v:ext="edit"&gt;&lt;/o:lock&gt;&lt;/v:shapetype&gt;&lt;v:shape id=Picture_x0020_1 style="VISIBILITY: visible; WIDTH: 237.75pt; HEIGHT: 117.75pt; mso-wrap-style: square" alt="http://i.msdn.microsoft.com/ms979213.uipc0102(en-us,MSDN.10).gif" type="#_x0000_t75" o:spid="_x0000_i1025"&gt;&lt;v:imagedata o:title="ms979213.uipc0102(en-us,MSDN.10)" src="file:///C:\DOCUME~1\arkum\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.gif"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&lt;/v:imagedata&gt;&lt;/v:shape&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 10pt 0in 0pt"&gt;&lt;FONT face=Cambria color=#4f81bd size=4&gt;Controller and Windows Workflow Foundation&lt;/FONT&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;Windows workflow foundation’s support for creating state machines makes it an excellent framework for creating our controller logic. You can think of the navigational logic in a UI process as a set of state transitions that the views undergo in response to user events. Workflow Foundation’s excellent designer support makes it more compelling to use it to define your controller logic&lt;/FONT&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 10pt 0in 0pt"&gt;&lt;FONT face=Cambria color=#4f81bd size=4&gt;Reusing the controller logic&lt;/FONT&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;Why should we ever reuse our controller logic? Enterprises are developing applications that already support multiple channels of interaction and most of them have ambitious plans for supporting more channels in future.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;A channel here means the medium that user interacts with your application. E.g. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;Web, Windows, Mobile are all possible channels. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;There are two compelling reasons for creating reusable controller logic. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; TEXT-ALIGN: justify; mso-list: l1 level1 lfo2"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;1.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;To support more channels in future without re-writing your controller logic.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 10pt 0.5in; TEXT-INDENT: -0.25in; TEXT-ALIGN: justify; mso-list: l1 level1 lfo2"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;2.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Modify the controller logic centrally and at once and reflect it on multiple channels simultaneously&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;Most of the complex processes an enterprise has, do not necessarily start and end in one channel, instead they span across multiple channels. In this case how do you carry forward your navigational logic from one channel to other? Again Windows Workflow Foundation provides excellent support with passivation and rehydration of the state of the workflow. This means that if you write your controller logic (Navigation logic) using Windows Workflow Foundation you may be able to passivate the workflow in one channel and rehydrate in another channel. But again the workflow has to be channel agnostic.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;Once you find that the reusability aspect of your controller logic is important, you start thinking how do I write my controller logic (State Machine Navigational Workflow) in a channel agnostic way? For e.g. you write a state machine workflow that drives a set of windows forms and you want the same workflow to drive a set of web forms or WPF forms. The best way to do is to create your workflow against a set of UI abstractions and depending on the channel the workflow is running it can drive either a set of windows forms or web forms or WPF forms.&lt;/FONT&gt;&lt;/P&gt;
&lt;H2 style="MARGIN: 10pt 0in 0pt"&gt;&lt;FONT face=Cambria color=#4f81bd size=4&gt;CCF2009 and Mce framework&lt;/FONT&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;CCF2009 ships with Multi Channel Engine (Mce) framework which helps you to create channel agnostic workflows for your controller logic. Mce defines a set of UI abstractions and helps you to define your navigational workflow (controller logic) in a channel agnostic manner. In this blog I will be talking about how you can leverage CCF and Mce to create channel independent reusable UI Process for your application&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9010816" width="1" height="1"&gt;</content><author><name>arkum</name><uri>http://blogs.msdn.com/arkum/ProfileUrlRedirect.ashx</uri></author><category term="UI Process" scheme="http://blogs.msdn.com/b/arkum/archive/tags/UI+Process/" /><category term="Windows Workflow Foundation" scheme="http://blogs.msdn.com/b/arkum/archive/tags/Windows+Workflow+Foundation/" /><category term="CCF" scheme="http://blogs.msdn.com/b/arkum/archive/tags/CCF/" /></entry></feed>