<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>The CRM Guys</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/thecrmguys/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/thecrmguys/feed.xml</link>
    <description>The blog of the Dynamics CRM Guys from Microsoft Consulting Services, UK.</description>
    <lastBuildDate>Wed, 17 Apr 2019 04:06:51 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Hands On with Dynamics CRM 2011's New ExecuteMultiple Request</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/hands-on-with-dynamics-crm-2011s-new-executemultiple-request</link>
      <pubDate>Wed, 09 Jan 2013 02:38:00 GMT</pubDate>
      <dc:creator><![CDATA[Dave Burman - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2013/01/09/hands-on-with-dynamics-crm-2011s-new-executemultiple-request/</guid>
      <description><![CDATA[Microsoft Dynamics 2011 Update Rollup 12 is now available, and includes a brand new...]]></description>
      <content:encoded><![CDATA[<p>Microsoft Dynamics 2011 <a href="https://support.microsoft.com/kb/2795627">Update Rollup 12 is now available</a>, and includes a brand new OrganizationRequest which allows developers to batch process other requests. &nbsp;In this article, we&rsquo;ll take a look at the new request, and explore why this new functionality can introduce huge performance gains in certain scenarios.</p>
<p><strong>The Problem</strong></p>
<p>Over the last couple of months, I&rsquo;ve been working with a customer making use of this new functionality to increase data load performance.&nbsp; Data load scenarios can be a huge challenge where there are performance requirements, especially when dealing with large data sets, and particularly when working with Dynamics CRM 2011 Online.</p>
<p>To understand why this can be a challenge, we need to understand how records are typically processed without ExecuteMultiple.&nbsp; Imagine we&rsquo;re writing an application that loads contact records into Dynamics CRM.&nbsp; At some point in the code, for each row in our data source that represents a contact, we&rsquo;ll send a single CreateRequest to the server.&nbsp; The journey that each request takes is illustrated below.</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/6136.Latency.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/6136.Latency.png"><img style="margin-right: auto; margin-left: auto; display: block;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/6136.Latency.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/6136.Latency.png" alt="" border="0" /></a></p>
<p>Each of the stages (1 &ndash; 4) takes a certain amount of time.&nbsp; The time taken for the request to travel from the client to the server (or the other way &ndash; stages 1 and 4) is known as the latency.&nbsp; You can view the latency you&rsquo;re getting between your client and server at <a href="https://%3Cserver%3E%3cport%3e">https://&lt;server&gt;:&lt;port&gt;/&lt;org&gt;/tools/diagnostics/diag.aspx</a>. &nbsp;For example, typically I get around 15ms latency between my client and server.&nbsp; To put that into context, that means 30ms of every request sent to Dynamics CRM is spent travelling.&nbsp; That&rsquo;s 8 minutes 20 seconds on a very simple one million record import without even doing any processing on either the client or server ((1,000,000 * 0.03) / 60).&nbsp; Furthermore, 15ms is a very low latency.&nbsp; Additionally, each request is received and authenticated by the server as it&rsquo;s received.&nbsp; Again, this fixed overhead on each request adds time to our data import.</p>
<p>It&rsquo;s also common to need to perform additional OrganizationRequests for each row.&nbsp; Imagine we&rsquo;d written our routine to perform a RetrieveMultiple query prior to creating the request, perhaps to look up a related value, or check if the record already exists. &nbsp;This doubles the amount of web requests, thus doubling the effects of the latency and processing overhead on the server.</p>
<p><strong>ExecuteMultiple</strong></p>
<p>ExecuteMultiple allows us to batch a number of other OrganizationRequests into a single request.&nbsp; These can be requests of different types, for example, a mixture of CreateRequest, UpdateRequest, and RetrieveMultipleRequests if desired.&nbsp; Each request is independent of other requests in the same batch, so you could not, for example, execute a CreateRequest followed by an UpdateRequest using the newly created ID within the same batch.&nbsp; Requests are executed in the order in which they are added to the request collection, and return results in the same order.</p>
<p>The default batch size (which is configurable for On-Premise installations &ndash; more on that later) is 1000.&nbsp; So in the 1 million record import example above, instead of sending 1,000,000 CreateRequests, we can send 1,000 batches of 1,000.&nbsp; With a latency of 15ms, the travelling time is cut from 8 minutes 20 seconds, to only 30 seconds ((1,000 * 0.03) / 60).&nbsp; Additionally, the server only receives and authenticates 1,000 records, saving additional processing time.</p>
<p>Obviously the impact of such a reduction in time needs to be looked at in context.&nbsp; If your 1 million record data import takes hours, a time saving of a few minutes may be negligible.&nbsp; Having said that, preliminary testing of the functionality I&rsquo;ve been working on recently has shown the use of ExecuteMultiple to increase the speed of simple imports to un-customized On-Premise environments by around 35-40%, which is a significant improvement. &nbsp;I would expect this difference to be less in more typical environments, for example, where server side customizations are present.</p>
<p>The new SDK page &ldquo;<a href="https://msdn.microsoft.com/en-us/library/jj863631.aspx">Use ExecuteMultiple to Improve Performance for Bulk Data Load</a>&rdquo; provides a great technical explanation of how to use the functionality, as well as a good code sample.</p>
<p><strong>Batch Size</strong></p>
<p>The maximum batch size allowed for an online deployment of Microsoft Dynamics CRM 2011 is 1,000, which is also the default value for an On-Premise installation.&nbsp; This value can be configured On-Premise if necessary, but it&rsquo;s important to understand the implications of doing so.</p>
<p>So why not insert say, 100,000 records in a single web request?&nbsp; There are a number of reasons why this is not a good idea.&nbsp; I decided to test this with another simple data import routine, creating 100,000 contact records, with first and last names, and an email address.&nbsp; I configured the ExecuteMultipleMaxBatchSize to 100,000 and ran my console application.</p>
<p><strong>Request Size</strong></p>
<p>Almost immediately, my application failed with a 404 error, which was odd as I had previously tested the application with a more sensible batch size (so I knew all URLs were correct) and the server was still working in the browser.&nbsp; On further investigation I noticed my single web request was 147MB, far exceeding the maxAllowedContentLength parameter set in the web.config on the server.&nbsp; I altered this accordingly and retried.</p>
<p>Again the application failed, although this time it took a little more time to do so.&nbsp; This time I found the answer in the server trace files &ndash; the maximum request length had been exceeded.&nbsp; Again I altered the server&rsquo;s web.config accordingly.</p>
<p><strong>Request Execution Time</strong></p>
<p>With the necessary web.config values in place, I retried my application.&nbsp; This time the application timed out after two minutes.&nbsp; My Dynamics CRM 2011 environment was a single machine, self-contained CRM and SQL machine with a small 4GB RAM.&nbsp; I find this is typically fine for development, but clearly the machine was struggling to create 100,000 records within the default timeout window.&nbsp; To accommodate this, I increased the timeout values on my OrganizationProxy object, setting them to timeout after 1 hour, rather than the default two minutes.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2110.Timeout.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2110.Timeout.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2110.Timeout.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2110.Timeout.png" alt="" border="0" /></a></p>
<p>I ran the application again, which ran for an hour and then timed out.</p>
<p><strong>Risk of Failure</strong></p>
<p>A common misconception that I&rsquo;ve heard a few people mention with ExecuteMultiple is that it is transaction aware.&nbsp; This is absolutely not the case.&nbsp; Each child request is processed in isolation, and if your ExecuteMultiple request fails midway through, any requests executed prior to failure are not rolled back.&nbsp; For example, after the 1 hour timeout mentioned above, I checked my database and noted 93,000 records had been successfully created.&nbsp; Unfortunately, my client code was unable to capture this information because the request timed out before a response was sent back, which, if this was a real environment, would have left me with a potentially difficult data clean-up exercise.</p>
<p><strong>Conclusion</strong></p>
<p>So when considering a non-default batch size, it&rsquo;s important to have an understanding of how this effects your ExecuteMultiple requests, to ensure the server will allow large requests to be accepted, and processed in a time that does not risk timeouts.</p>
<p>The ExecuteMultiple request is a great enhancement to the SDK that offers significant performance gains when dealing with bulk operations.&nbsp; Version 5.0.13 of the SDK is available now, <a href="https://www.microsoft.com/en-us/download/details.aspx?id=24004">here</a>.</p>
<table border="0" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="117"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png"><img title="Dave Burman" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png" alt="Dave" width="100" height="100" border="0" /></a></td>
<td valign="top" width="283">
<p><strong><a href="https://blogs.msdn.com/b/thecrmguys/archive/tags/dave+burman/">Dave Burman</a></strong> <br />Consultant <br />Microsoft Consulting Services UK</p>
<p><a href="https://blogs.msdn.com/b/thecrmguys/archive/2012/03/14/dave-burman.aspx">View my bio</a></p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>Unit Testing Microsoft Dynamics CRM 2011 Plug-ins with Microsoft Fakes</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/unit-testing-microsoft-dynamics-crm-2011-plug-ins-with-microsoft-fakes</link>
      <pubDate>Wed, 10 Oct 2012 05:48:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2012/10/10/unit-testing-microsoft-dynamics-crm-2011-plug-ins-with-microsoft-fakes/</guid>
      <description><![CDATA[Visual Studio 2012 Ultimate ships with a new isolation framework called Microsoft Fakes. This...]]></description>
      <content:encoded><![CDATA[<p>Visual Studio 2012 Ultimate ships with a new isolation framework called Microsoft Fakes. This article describes how we can use Microsoft Fakes to unit test plug-in code without a dependency on a Microsoft Dynamics CRM 2011 server, allowing us to easily test logic in isolation, from a known state.&nbsp; This post assumes a certain level of familiarity in coding Microsoft Dynamics CRM 2011 plug-ins.</p>
<p><b>Why unit test?</b></p>
<p>Bugs are an inevitable side effect of any software development. As software evolves, changes in code can lead to unintentional side effects. Bugs identified during development are much easier and cheaper to fix than those discovered during later stages of the application lifecycle. Although there is a certain level of investment required to build a suite of unit tests, once built they are a valuable asset for the on-going early detection of bugs.</p>
<p><b>What&rsquo;s the challenge?</b></p>
<p>There are a number of challenges in writing unit tests for Microsoft&nbsp;Dynamics CRM plug-ins, generally introduced by external dependencies. For example, plug-in logic is typically heavily dependent on the contextual information passed into the plug-in by Microsoft Dynamics CRM when the plug-in is triggered. Any unit test that invokes plug-in logic must somehow pass in the required information.</p>
<p>Similarly, plug-in code commonly interacts with the Microsoft Dynamics CRM server using the <a href="https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.iorganizationservice.aspx" target="_blank">IOrganizationService</a> object to query and modify Microsoft&nbsp;Dynamics CRM data, so it&rsquo;s common for plug-in logic to become heavily dependent on the state of that data. To write effective unit tests, this data dependency needs to be removed.</p>
<p>Also, plug-in logic is commonly dependent on logic stored in external assemblies. For example, a plug-in may reference the System.DateTime.Now property, and change its behaviour dependent on the returned DateTime value. This value is obviously dependent on the time at which the code is executed, so any unit test needs to have some way to overcome this.</p>
<p>This is not an exhaustive list. Plug-ins can be dependent on all sorts of external dependencies; web services, databases, local files and registry settings to name a few, but the concept is always the same; to effectively unit test, we need to be able to run the code in complete isolation.</p>
<p><b>Enter Microsoft Fakes</b></p>
<p>Microsoft Fakes allows us to address these types of challenges by providing a way of simulating external behaviour without modifying our original logic. Let&rsquo;s consider a trivial plug-in to demonstrate how this can be achieved.</p>
<p><b>Example 1 &ndash;A plug-in that sets a field value</b></p>
<p>Imagine you have a requirement to write a plug-in that sets the value of a field during record creation. We may start with an implementation such as the one below, which could be triggered by the Post Create event of the entity in question:</p>
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b7f12ffc-8420-47b4-9acb-ce0f4141ca6c" style="margin: 0px; padding: 0px; float: none; display: inline;">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;"><ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;" start="1">
<li><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">void</span><span style="background: #ffffff; color: #000000;"> Execute(</span><span style="background: #ffffff; color: #2b91af;">IServiceProvider</span><span style="background: #ffffff; color: #000000;"> serviceProvider)</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> context = (</span><span style="background: #ffffff; color: #2b91af;">IPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">)serviceProvider.GetService(</span><span style="background: #ffffff; color: #0000ff;">typeof</span><span style="background: #ffffff; color: #000000;">(</span><span style="background: #ffffff; color: #2b91af;">IPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">));</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> entity = (</span><span style="background: #ffffff; color: #2b91af;">Entity</span><span style="background: #ffffff; color: #000000;">)context.InputParameters[</span><span style="background: #ffffff; color: #a31515;">"Target"</span><span style="background: #ffffff; color: #000000;">];</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">entity[</span><span style="background: #ffffff; color: #a31515;">"new_pluginexecuted"</span><span style="background: #ffffff; color: #000000;">] = </span><span style="background: #ffffff; color: #0000ff;">true</span><span style="background: #ffffff; color: #000000;">;</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
</ol></div>
</div>
</div>
<p>&nbsp;</p>
<p>The implementation obtains the <a href="https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.ipluginexecutioncontext.aspx" target="_blank">IPluginExecutionContext</a> object from the <a href="https://msdn.microsoft.com/en-us/library/System.IServiceProvider(v=vs.100).aspx" target="_blank">IServiceProvider</a> object passed in by Dynamics CRM. From there, we are able to access the record being created, and set a value accordingly.</p>
<p>We can now write a test method in a separate unit test project to check that this execution produces the expected outcome. Rather than writing a custom class that implements IServiceProvider, we can use the new Fakes functionality to create stubs of the required objects, and test that the plug-in code performs correctly.</p>
<p>Create a unit test project through the new project wizard, you&rsquo;ll find the project template in the Visual C# -&gt; Test area (or Visual Basic &ndash; this walkthrough assumes C#). In the new project, add a reference to the plug-in project, and to Microsoft.Xrm.Sdk.dll and System.Runtime.Serialization.dll. If you right click the newly added Microsoft.Xrm.Sdk.dll assembly (or any other referenced assembly), you&rsquo;ll notice the option to &ldquo;Add Fakes Assembly&rdquo;. Click this option, and you should see a new reference to Microsoft.Xrm.Sdk.5.0.0.0.Fakes assembly. Also select this option for System, which should create a System.4.0.0.0.Fakes reference.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/3223.image_41D33615.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/3223.image_5F00_41D33615.png"><img width="244" height="143" title="image" style="margin-right: auto; margin-left: auto; display: block;" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/1157.image_thumb_2EB20969.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/1157.image_5F00_thumb_5F00_2EB20969.png" border="0" /></a></p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/4278.image_466940CF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/4278.image_5F00_466940CF.png"><img width="244" height="211" title="image" style="margin-right: auto; margin-left: auto; display: block;" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/4774.image_thumb_70693EF7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/4774.image_5F00_thumb_5F00_70693EF7.png" border="0" /></a></p>
<p>Locate the TestMethod1() method within the UnitTest1.cs class file. You can rename the class and method if you wish. In this method, we&rsquo;ll create a number of stub objects, and then pass them into the plug-in method to test the functionality.</p>
<p>Our plug-in&rsquo;s Execute method needs a System.IServiceProvider parameter. Because we&rsquo;ve faked the System assembly, we already have a class that we can use &ndash; System.<b>Fakes</b>.<b>Stub</b>IServiceProvider. This class is interchangeable with the System.IServiceProvider (so we can pass an instantiated StubIServiceProvider into the Execute method), and allows us to specify a delegate that is executed when properties or methods are invoked. We can set properties on this object to return other stub objects, ultimately building up an object that will respond to method calls executed by our plug-in in a predictable way. To demonstrate this, let&rsquo;s have a look at what our plug-in will do.</p>
<ol>
<li>Call the GetService method on the IServiceProvider object, passing in the IPluginExecutionContext type as a parameter, and receive an IPluginExecutionContext object</li>
<li>Access the InputParameters indexed property, passing the string parameter &ldquo;Target&rdquo;, and cast the returned value to an Entity object.</li>
<li>Set the &ldquo;new_pluginexecuted&rdquo; attribute on the entity to true.</li>
</ol>
<p>The following test code sets up the StubIServiceProvider object with&nbsp;just enough state to react to the above logic in a manner that will test the effect of the plug-in code.</p>
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5947dd2d-3ee0-4238-8f30-b1ef2158e28d" style="margin: 0px; padding: 0px; float: none; display: inline;">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;" start="1">
<li><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> serviceProvider = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">StubIServiceProvider</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> context = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">StubIPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li><span style="background: #ffffff; color: #000000;">serviceProvider.GetServiceType = </span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">(type) =&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">if</span><span style="background: #ffffff; color: #000000;"> (type == </span><span style="background: #ffffff; color: #0000ff;">typeof</span><span style="background: #ffffff; color: #000000;">(</span><span style="background: #ffffff; color: #2b91af;">IPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">))</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> context;</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">else</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">null</span><span style="background: #ffffff; color: #000000;">;</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">};</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> inputParameters = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">ParameterCollection</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li><span style="background: #ffffff; color: #000000;">context.InputParametersGet = () =&gt; { </span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> inputParameters; };</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> testEntity = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">Entity</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #000000;">inputParameters.Add(</span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">KeyValuePair</span><span style="background: #ffffff; color: #000000;">&lt;</span><span style="background: #ffffff; color: #0000ff;">string</span><span style="background: #ffffff; color: #000000;">,</span><span style="background: #ffffff; color: #0000ff;">object</span><span style="background: #ffffff; color: #000000;">&gt;(</span><span style="background: #ffffff; color: #a31515;">"Target"</span><span style="background: #ffffff; color: #000000;">, testEntity));</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> plugin = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">SetPluginExecutedPlugin</span><span style="background: #ffffff; color: #000000;">();</span></li>
</ol></div>
</div>
</div>
<p>&nbsp;</p>
<p>After we&rsquo;ve arranged the objects, we can perform the action we wish to test, which in this case is the Execute method. Following this execution, we can check our test objects have been affected in the right way using assertion methods. Here&rsquo;s the complete test class:</p>
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a5c760c8-7814-4366-b088-089564e93244" style="margin: 0px; padding: 0px; float: none; display: inline;">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;" start="1">
<li><span style="background: #ffffff; color: #0000ff;">using</span><span style="background: #ffffff; color: #000000;"> System.Collections.Generic;</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #0000ff;">using</span><span style="background: #ffffff; color: #000000;"> System.Fakes;</span></li>
<li><span style="background: #ffffff; color: #0000ff;">using</span><span style="background: #ffffff; color: #000000;"> Microsoft.VisualStudio.TestTools.UnitTesting;</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #0000ff;">using</span><span style="background: #ffffff; color: #000000;"> Microsoft.Xrm.Sdk;</span></li>
<li><span style="background: #ffffff; color: #0000ff;">using</span><span style="background: #ffffff; color: #000000;"> Microsoft.Xrm.Sdk.Fakes;</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li><span style="background: #ffffff; color: #0000ff;">namespace</span><span style="background: #ffffff; color: #000000;"> Test_Plugin.Tests.Unit</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">TestClass</span><span style="background: #ffffff; color: #000000;">]</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">class</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">SetPluginExecutedPluginUnitTests</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">TestMethod</span><span style="background: #ffffff; color: #000000;">]</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">void</span><span style="background: #ffffff; color: #000000;"> TestMethod1()</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #008000;">//Arrange</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> serviceProvider = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">StubIServiceProvider</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> context = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">StubIPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">serviceProvider.GetServiceType = </span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">(type) =&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">if</span><span style="background: #ffffff; color: #000000;"> (type == </span><span style="background: #ffffff; color: #0000ff;">typeof</span><span style="background: #ffffff; color: #000000;">(</span><span style="background: #ffffff; color: #2b91af;">IPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">))</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> context;</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">else</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">null</span><span style="background: #ffffff; color: #000000;">;</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">};</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> inputParameters = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">ParameterCollection</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">context.InputParametersGet = () =&gt; { </span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> inputParameters; };</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> testEntity = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">Entity</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">inputParameters.Add(</span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">KeyValuePair</span><span style="background: #ffffff; color: #000000;">&lt;</span><span style="background: #ffffff; color: #0000ff;">string</span><span style="background: #ffffff; color: #000000;">,</span><span style="background: #ffffff; color: #0000ff;">object</span><span style="background: #ffffff; color: #000000;">&gt;(</span><span style="background: #ffffff; color: #a31515;">"Target"</span><span style="background: #ffffff; color: #000000;">, testEntity));</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> plugin = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">SetPluginExecutedPlugin</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #008000;">//Act</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">plugin.Execute(serviceProvider);</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #008000;">//Assert</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #2b91af;">Assert</span><span style="background: #ffffff; color: #000000;">.AreEqual&lt;</span><span style="background: #ffffff; color: #0000ff;">bool</span><span style="background: #ffffff; color: #000000;">&gt;(</span><span style="background: #ffffff; color: #0000ff;">true</span><span style="background: #ffffff; color: #000000;">, testEntity.GetAttributeValue&lt;</span><span style="background: #ffffff; color: #0000ff;">bool</span><span style="background: #ffffff; color: #000000;">&gt;(</span><span style="background: #ffffff; color: #a31515;">"new_pluginexecuted"</span><span style="background: #ffffff; color: #000000;">), </span><span style="background: #ffffff; color: #a31515;">"Set new_pluginexecuted attribute value was not expected"</span><span style="background: #ffffff; color: #000000;">);</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #000000;">}</span></li>
</ol></div>
</div>
</div>
<p>&nbsp;</p>
<p>My assertion in this test is quite straightforward; I am looking at the Entity object I set up, and checking that the field has been set to true. Running this unit test indicates success, and this plug-in hasn&rsquo;t even been deployed to a CRM server yet.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/4375.image_360DC916.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/4375.image_5F00_360DC916.png"><img width="244" height="168" title="image" style="margin-right: auto; margin-left: auto; display: block;" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0243.image_thumb_0DFB19F7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0243.image_5F00_thumb_5F00_0DFB19F7.png" border="0" /></a></p>
<p><b>Unit test results</b></p>
<p>The fact that my unit test has run successfully does <b>not</b> mean my plug-in is correct. I could have made some logical error in my plug-in code that has an unintended side effect, or even have logical errors in my test code. The test merely indicates that it affects my prepared stub objects in the way I expected. The value in the unit test is in the fact that I now have some code that consumes my plug-in code, which will always execute in a predictable way with no external dependencies. Other testing that invokes my plug-in code should be performed, and ideally if a bug is found, more unit tests should be written to expose the bug for continued retesting at a later date.</p>
<p><b>Example 2 &ndash; A more typical plug-in</b></p>
<p>Let&rsquo;s consider a slightly more complex plug-in which may be used in a real system. Suppose your customer has a requirement to prevent cases being re-activated more than 30 days after they are have been closed. This could be implemented with the following code (for the purposes of this example, imagine a different plug-in sets the value of new_dateclosed when case is closed).</p>
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a87f2c72-c924-4f97-97b5-3c731ea4d99c" style="margin: 0px; padding: 0px; float: none; display: inline;">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;" start="1">
<li><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">void</span><span style="background: #ffffff; color: #000000;"> Execute(</span><span style="background: #ffffff; color: #2b91af;">IServiceProvider</span><span style="background: #ffffff; color: #000000;"> serviceProvider)</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> context = (</span><span style="background: #ffffff; color: #2b91af;">IPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">)serviceProvider.GetService(</span><span style="background: #ffffff; color: #0000ff;">typeof</span><span style="background: #ffffff; color: #000000;">(</span><span style="background: #ffffff; color: #2b91af;">IPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">));</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> entity = context.InputParameters[</span><span style="background: #ffffff; color: #a31515;">"Target"</span><span style="background: #ffffff; color: #000000;">] </span><span style="background: #ffffff; color: #0000ff;">as</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">Entity</span><span style="background: #ffffff; color: #000000;">;</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #008000;">//Establish case reactivation is being attempted - omitted to simplify example</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> dateClosed = entity.GetAttributeValue&lt;</span><span style="background: #ffffff; color: #2b91af;">DateTime</span><span style="background: #ffffff; color: #000000;">&gt;(</span><span style="background: #ffffff; color: #a31515;">"new_dateclosed"</span><span style="background: #ffffff; color: #000000;">);</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">if</span><span style="background: #ffffff; color: #000000;"> (dateClosed.AddDays(30) &lt; </span><span style="background: #ffffff; color: #2b91af;">DateTime</span><span style="background: #ffffff; color: #000000;">.Now)</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">throw</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">InvalidPluginExecutionException</span><span style="background: #ffffff; color: #000000;">(</span><span style="background: #ffffff; color: #a31515;">"This case has been closed for too long to reopen."</span><span style="background: #ffffff; color: #000000;">);</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li><span style="background: #ffffff; color: #000000;">}</span></li>
</ol></div>
</div>
</div>
<p>&nbsp;</p>
<p>We can write a unit test similar to the last example to ascertain whether the exception is correctly thrown under the right conditions, and we can control the value of new_dateclosed very easily.</p>
<p>Here&rsquo;s an example of two unit tests that test these conditions. TestMethod1 expects an exception (note the [ExpectedException] method attribute), and TestMethod2 does not. The code is slightly differently structured here, as I&rsquo;ve used TestInitialize and TestCleanup methods to setup and tear down my tests, saving me repeating the context setup code.</p>
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5636aa98-fc2a-45cf-8954-f40a73725394" style="margin: 0px; padding: 0px; float: none; display: inline;">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;" start="1">
<li><span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">TestClass</span><span style="background: #ffffff; color: #000000;">]</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">class</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">PreventCaseReopenPluginUnitTest</span></li>
<li><span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">private</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">StubIServiceProvider</span><span style="background: #ffffff; color: #000000;"> ServiceProvider { </span><span style="background: #ffffff; color: #0000ff;">get</span><span style="background: #ffffff; color: #000000;">; </span><span style="background: #ffffff; color: #0000ff;">set</span><span style="background: #ffffff; color: #000000;">; }</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">private</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">Entity</span><span style="background: #ffffff; color: #000000;"> TestEntity { </span><span style="background: #ffffff; color: #0000ff;">get</span><span style="background: #ffffff; color: #000000;">; </span><span style="background: #ffffff; color: #0000ff;">set</span><span style="background: #ffffff; color: #000000;">; }</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">TestInitialize</span><span style="background: #ffffff; color: #000000;">]</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">void</span><span style="background: #ffffff; color: #000000;"> Init()</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> context = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">StubIPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">ServiceProvider = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">StubIServiceProvider</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">ServiceProvider.GetServiceType =</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">(type) =&gt;</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">if</span><span style="background: #ffffff; color: #000000;"> (type == </span><span style="background: #ffffff; color: #0000ff;">typeof</span><span style="background: #ffffff; color: #000000;">(</span><span style="background: #ffffff; color: #2b91af;">IPluginExecutionContext</span><span style="background: #ffffff; color: #000000;">))</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> context;</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">else</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">null</span><span style="background: #ffffff; color: #000000;">;</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">};</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> inputParameters = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">ParameterCollection</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">context.InputParametersGet = () =&gt; { </span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> inputParameters; };</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">TestEntity = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">Entity</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">inputParameters.Add(</span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> System.Collections.Generic.</span><span style="background: #ffffff; color: #2b91af;">KeyValuePair</span><span style="background: #ffffff; color: #000000;">&lt;</span><span style="background: #ffffff; color: #0000ff;">string</span><span style="background: #ffffff; color: #000000;">, </span><span style="background: #ffffff; color: #0000ff;">object</span><span style="background: #ffffff; color: #000000;">&gt;(</span><span style="background: #ffffff; color: #a31515;">"Target"</span><span style="background: #ffffff; color: #000000;">, TestEntity));</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">TestCleanup</span><span style="background: #ffffff; color: #000000;">]</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">void</span><span style="background: #ffffff; color: #000000;"> Cleanup()</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">ServiceProvider = </span><span style="background: #ffffff; color: #0000ff;">null</span><span style="background: #ffffff; color: #000000;">;</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">TestEntity = </span><span style="background: #ffffff; color: #0000ff;">null</span><span style="background: #ffffff; color: #000000;">;</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">TestMethod</span><span style="background: #ffffff; color: #000000;">]</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">ExpectedException</span><span style="background: #ffffff; color: #000000;">(</span><span style="background: #ffffff; color: #0000ff;">typeof</span><span style="background: #ffffff; color: #000000;">(</span><span style="background: #ffffff; color: #2b91af;">InvalidPluginExecutionException</span><span style="background: #ffffff; color: #000000;">), </span><span style="background: #ffffff; color: #a31515;">"Exception not thrown"</span><span style="background: #ffffff; color: #000000;">)]</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">void</span><span style="background: #ffffff; color: #000000;"> TestMethod1()</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">TestEntity[</span><span style="background: #ffffff; color: #a31515;">"new_dateclosed"</span><span style="background: #ffffff; color: #000000;">] = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">DateTime</span><span style="background: #ffffff; color: #000000;">(2010, 1, 1);</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> plugin = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">PreventCaseReopenPlugin</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">plugin.Execute(ServiceProvider);</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">TestMethod</span><span style="background: #ffffff; color: #000000;">]</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">void</span><span style="background: #ffffff; color: #000000;"> TestMethod2()</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">TestEntity[</span><span style="background: #ffffff; color: #a31515;">"new_dateclosed"</span><span style="background: #ffffff; color: #000000;">] = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">DateTime</span><span style="background: #ffffff; color: #000000;">(2012, 11, 1);</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> plugin = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">PreventCaseReopenPlugin</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">plugin.Execute(ServiceProvider);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #000000;">}</span></li>
</ol></div>
</div>
</div>
<p>&nbsp;</p>
<p>However, there is another subtle dependency in this code; DateTime.Now. The value returned by this property varies depending on the date and time that the code is run, which means our unit tests may behave differently depending on when we run them. Both tests pass now, but TestMethod2 will fail if I run the unit test a couple of months from now. To complicate matters, DateTime.Now is a static property, so we cannot use a dependency injection approach to alter the behaviour of the property. To solve this problem without altering the plug-in code, we need to use a shim.</p>
<p><b>Shims</b></p>
<p>Like stubs, shims can also be used to alter method behaviour, but work by intercepting method calls at runtime, rather than being injected into method calls as parameters. By using the ShimDateTime class (generated by faking the System assembly earlier on), we can redirect calls to DateTime.Now to our own lambda expression.</p>
<p>The following code demonstrates this approach, ensuring that any call to DateTime.Now within the context of the ShimsContext returns a fixed DateTime object.</p>
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:997b27cc-52ff-4420-82fc-c38f0f2015ef" style="margin: 0px; padding: 0px; float: none; display: inline;">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;" start="1">
<li><span style="background: #ffffff; color: #000000;">[</span><span style="background: #ffffff; color: #2b91af;">TestMethod</span><span style="background: #ffffff; color: #000000;">]</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #0000ff;">public</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">void</span><span style="background: #ffffff; color: #000000;"> TestMethod3()</span></li>
<li><span style="background: #ffffff; color: #000000;">{</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">TestEntity[</span><span style="background: #ffffff; color: #a31515;">"new_dateclosed"</span><span style="background: #ffffff; color: #000000;">] = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">DateTime</span><span style="background: #ffffff; color: #000000;">(2012, 11, 1);</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">var</span><span style="background: #ffffff; color: #000000;"> plugin = </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">PreventCaseReopenPlugin</span><span style="background: #ffffff; color: #000000;">();</span></li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">using</span><span style="background: #ffffff; color: #000000;"> (</span><span style="background: #ffffff; color: #2b91af;">ShimsContext</span><span style="background: #ffffff; color: #000000;">.Create())</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">{</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">System.Fakes.</span><span style="background: #ffffff; color: #2b91af;">ShimDateTime</span><span style="background: #ffffff; color: #000000;">.NowGet = () =&gt; {</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;"></span><span style="background: #ffffff; color: #0000ff;">return</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #0000ff;">new</span><span style="background: #ffffff; color: #000000;"> </span><span style="background: #ffffff; color: #2b91af;">DateTime</span><span style="background: #ffffff; color: #000000;">(2012, 1, 15);</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">};</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">plugin.Execute(ServiceProvider);</span></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #ffffff; color: #000000;">}</span></li>
<li style="background: #f3f3f3;"><span style="background: #ffffff; color: #000000;">}</span></li>
</ol></div>
</div>
</div>
<p><strong>Conclusion</strong></p>
<p>The techniques here can be extended with relative ease to simulate IOrganizationService operations, database calls, external web service calls and beyond. A suite of unit tests is a valuable asset to a developer writing code that is susceptible to change in the future, and the new Microsoft Fakes isolation framework included in Visual Studio 2012 Ultimate allows developers to simplify the process of writing test code that effectively tests plug-in logic.</p>
<table style="width: 400px;" border="0" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td width="117" valign="top"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png"><img width="100" height="100" title="Dave Burman" style="margin-right: auto; margin-left: auto; float: none; display: block;" alt="Dave" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png" border="0" /></a></td>
<td width="283" valign="top">
<p><b><a href="https://blogs.msdn.com/b/thecrmguys/archive/tags/dave+burman/">Dave Burman</a></b> <br />Consultant <br />Microsoft Consulting Services UK</p>
<p><a href="https://blogs.msdn.com/b/thecrmguys/archive/2012/03/14/dave-burman.aspx">View my bio</a></p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>Silverlight Async with Visual Studio 2012</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/silverlight-async-with-visual-studio-2012</link>
      <pubDate>Tue, 28 Aug 2012 02:07:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2012/08/28/silverlight-async-with-visual-studio-2012/</guid>
      <description><![CDATA[A frequent complaint I hear from developers working on Silverlight applications for Microsoft...]]></description>
      <content:encoded><![CDATA[<p>A frequent complaint I hear from developers working on Silverlight applications for Microsoft Dynamics CRM is that they have to use asynchronous methods when communicating with the CRM web services. Asynchronous methods and callbacks are not particularly complex concepts or even challenging to program, but real complexity arises when you have a dependency chain of asynchronous methods, leading to high volumes of heavily indented code or scattered logic that is counter-intuitive to the intended logic of the application. With the upcoming release of Visual Studio 2012, this is no longer a problem!</p>  <p><b>UI Responsiveness</b></p>  <p>To ensure the UI remains responsive, Silverlight does not allow us to perform a call to the WCF endpoint whilst blocking the UI thread. This means when we perform a web service request, a thread is spawned to wait for the response. This is great for users, as it ensures their Silverlight applications do not lock up when web service queries are made. However, for developers, this can be a real headache. Multithreaded applications are far more complicated to write than single threaded ones. For one, developers need to worry about cross-thread object access; code run in a background thread needs to be dispatched back up to the UI thread before it can modify UI components. Secondly, developers are required to write callbacks to handle responses from the server. These quickly become unmanageable, especially when nested.</p>  <p><b>Asynchronous Methods &amp; Callbacks</b></p>  <p>Typically when you retrieve data from CRM, you want to do something with the retrieved data. This could be as simple as counting the results of a query, or inspecting the value of a field. I can’t imagine a reason you would want to invoke the Retrieve or RetrieveMultiple operations and not want to inspect the returned value(s).</p>  <p>Let’s consider an example to demonstrate the differences between programming this synchronously and asynchronously. Let’s say you’re working with the WCF endpoint. Your requirement is to query CRM for all contacts in the system, and display their names to the user.</p>  <p>This is how it’s done in a synchronous way:</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:eda3865e-6680-4df4-80c9-e25e62a46dd6" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> SynchronousExample(</span><span style="background:#ffffff;color:#2b91af">IOrganizationService</span><span style="background:#ffffff;color:#000000"> service)</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Build the query</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> query = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">QueryExpression</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">EntityName = </span><span style="background:#ffffff;color:#a31515">&quot;contact&quot;</span><span style="background:#ffffff;color:#000000">,</span></li> <li>        <span style="background:#ffffff;color:#000000">ColumnSet = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ColumnSet</span><span style="background:#ffffff;color:#000000"> { Columns = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000">[] { </span><span style="background:#ffffff;color:#a31515">&quot;fullname&quot;</span><span style="background:#ffffff;color:#000000"> } }</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">};</span></li> <li>            <span style="background:#ffffff;color:#000000"></span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Send it to the server and receive a response</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> response = service.RetrieveMultiple(query);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Iterate across returned entities and output fullname</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">foreach</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> contact </span><span style="background:#ffffff;color:#0000ff">in</span><span style="background:#ffffff;color:#000000"> response.Entities)</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">Console</span><span style="background:#ffffff;color:#000000">.WriteLine(contact.Attributes[0]);</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>&#160;</p>  <p>However, we can’t do this synchronously in Silverlight, so we’d have to write a callback to specify what needs to happen when the response is received.</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cee19f47-18c6-4319-9c44-07f5469b9c4a" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> AsynchronousExample(</span><span style="background:#ffffff;color:#2b91af">IOrganizationService</span><span style="background:#ffffff;color:#000000"> service)</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Build the query</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> query = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">QueryExpression</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">EntityName = </span><span style="background:#ffffff;color:#a31515">&quot;contact&quot;</span><span style="background:#ffffff;color:#000000">,</span></li> <li>        <span style="background:#ffffff;color:#000000">ColumnSet = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ColumnSet</span><span style="background:#ffffff;color:#000000"> { Columns = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ObservableCollection</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000">&gt; { </span><span style="background:#ffffff;color:#a31515">&quot;fullname&quot;</span><span style="background:#ffffff;color:#000000"> } }</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">};</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Send it to the server</span></li> <li>    <span style="background:#ffffff;color:#000000">service.BeginRetrieveMultiple(query, (result) =&gt; {</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Define a callback that indicates what to do when the response is recieved</span></li> <li>                <span style="background:#ffffff;color:#000000"></span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Capture the response</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> response = ((</span><span style="background:#ffffff;color:#2b91af">IOrganizationService</span><span style="background:#ffffff;color:#000000">)result.AsyncState).EndRetrieveMultiple(result);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Dispatch back up to the UI thread to avoid thread permission exceptions</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">Dispatcher.BeginInvoke(</span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Action</span><span style="background:#ffffff;color:#000000">(</span></li> <li>            <span style="background:#ffffff;color:#000000">() =&gt; {</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Iterate across results and output fullname</span></li> <li>                    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">foreach</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> contact </span><span style="background:#ffffff;color:#0000ff">in</span><span style="background:#ffffff;color:#000000"> response.Entities)</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">{</span></li> <li>                        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">MessageBox</span><span style="background:#ffffff;color:#000000">.Show(contact.GetAttributeValue&lt;</span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000">&gt;(</span><span style="background:#ffffff;color:#a31515">&quot;fullname&quot;</span><span style="background:#ffffff;color:#000000">));</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">}</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">)</span></li> <li>        <span style="background:#ffffff;color:#000000">);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>                <span style="background:#ffffff;color:#000000"></span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">}, service);</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>&#160;</p>  <p>So even with this simple example we can see there’s a lot of added complexity in the code. Not only is the code to send and receive the request more verbose, there’s also added complexity introduced as the response is executed on a different thread to the UI. Rather than using the IOrganizationService interface, we can use the events available to us on the OrganizationServiceClient, but the structure of the code is almost identical, with the same problems.</p>  <p>Taking this one step further, suppose we want to run a separate query against each of these contacts to retrieve some related information. In the asynchronous example we have to introduce another nested callback of a similar quantity. This quickly becomes unmanageable.</p>  <p>One approach to making this more manageable is to break the callback into a separate method. This approach goes some way to improving the maintainability of the code. However, it’s still quite verbose and we’ve still got the problem of having to dispatch back up to the UI thread in the response.</p>  <p><b>A better way</b></p>  <p>Writing code like this quickly hides the fundamental purpose of the code, making the logic very difficult to read. Wouldn’t it be great if we could write single threaded Silverlight applications without blocking the UI thread? Well now we can!</p>  <p>.NET 4.5 introduced new language keywords to overcome exactly this problem, and with Visual Studio 2012 we can use these keywords with Silverlight 5. These enhancements were first introduced as the Async CTP for .NET 4.0, and although the CTP is licenced for production use, it is not recommended. However, with the upcoming release of .NET 4.5, the keywords have been built into the language, and with the help of the <a href="https://www.microsoft.com/en-us/download/details.aspx?id=29576">Async Targetting Pack</a>, we can use these features in Silverlight 5 applications.</p>  <p>I won’t go into huge detail on the inner workings of the new language features, rather a brief overview, but if you’re interested in some of the detail, I would highly recommend giving <a href="https://channel9.msdn.com/Shows/Going+Deep/Mads-Torgersen-Inside-C-Async">this video</a> a watch.</p>  <p>The new async features are built on top of the TPL introduced in .NET 4.0, and introduce two new language constructs; async and await. Developers use async to indicate that a method runs asynchronously, and await to indicate that execution should pause until a task has been completed. Conveniently for Silverlight developers, this can all happen on the UI thread without having to block.</p>  <p><b>Setting It Up</b></p>  <p>The best way to demonstrate the benefits is to see it in action, but before we can do that we need to install the Async Targetting Pack. Begin by creating a new Silverlight application in Visual Studio    <br />2012:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/2577.image_55C35833.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/2577.image_5F00_55C35833.png"><img title="image" style="margin-right: auto; margin-left: auto; float: none; display: block;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/1817.image_thumb_4CF34FE7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/1817.image_5F00_thumb_5F00_4CF34FE7.png" width="605" height="420" /></a></p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/2480.image_792FD6CB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/2480.image_5F00_792FD6CB.png"><img title="image" style="margin-right: auto; margin-left: auto; float: none; display: block;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/2072.image_thumb_7F0A7A64.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/2072.image_5F00_thumb_5F00_7F0A7A64.png" width="527" height="421" /></a></p>  <p>Then in the newly created project, select Tools -&gt; Library Package Manager -&gt; Package Manager Console</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/5127.image_1DE0EE43.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/5127.image_5F00_1DE0EE43.png"><img title="image" style="margin-right: auto; margin-left: auto; float: none; display: block;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0743.image_thumb_352BF2B4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0743.image_5F00_thumb_5F00_352BF2B4.png" width="605" height="333" /></a></p>  <p>and in the Package Manager Console type the following and press enter:</p>  <p>Install-Package Microsoft.CompilerServices.AsyncTargetingPack</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/4643.image_337B26E0.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/4643.image_5F00_337B26E0.png"><img title="image" style="margin-right: auto; margin-left: auto; float: none; display: block;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/6116.image_thumb_0A9011D7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/6116.image_5F00_thumb_5F00_0A9011D7.png" width="605" height="273" /></a></p>  <p></p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0250.image_6F7742C8.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0250.image_5F00_6F7742C8.png"><img title="image" style="margin-right: auto; margin-left: auto; float: none; display: block;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/2500.image_thumb_53F240C5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/2500.image_5F00_thumb_5F00_53F240C5.png" width="606" height="307" /></a></p>  <p>This only takes a few seconds to install, and once complete allows you to use the new language features within your application.</p>  <p>For this example, I have also configured the project to use the CRM SOAP endpoint as detailed in <a href="https://msdn.microsoft.com/en-us/library/gg594452.aspx">this SDK article</a>.</p>  <p>Finally, I have also created a class of extension methods that enable the IOrganizationService methods to be used asynchronously. Create a new class in your project called AsyncExtensions.cs and insert the following code. Ensure the namespace matches the one that your service reference has.</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:09f60d64-1ff1-4371-a6e0-4b2a1a0d2850" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 3em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> System;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> System.Threading.Tasks;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">namespace</span><span style="background:#ffffff;color:#000000"> SilverlightApplication1.CrmSdk</span></li> <li><span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">class</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">AsyncExtensions</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000"> Associate(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> IOrganizationService service, </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> entityName, System.</span><span style="background:#ffffff;color:#2b91af">Guid</span><span style="background:#ffffff;color:#000000"> entityId, Relationship relationship, EntityReferenceCollection relatedEntities)</span></li> <li>        <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000">&gt;();</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">service.BeginAssociate(entityName, entityId, relationship, relatedEntities, (asyncResult) =&gt;</span></li> <li>            <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li>                <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">((IOrganizationService)asyncResult.AsyncState).EndAssociate(asyncResult);</span></li> <li>                    <span style="background:#ffffff;color:#000000">tcs.TrySetResult(</span><span style="background:#ffffff;color:#0000ff">null</span><span style="background:#ffffff;color:#000000">);</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">}</span></li> <li>                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">{</span></li> <li>                    <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">}</span></li> <li>            <span style="background:#ffffff;color:#000000">}, service);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#2b91af">Guid</span><span style="background:#ffffff;color:#000000">&gt; Create(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> IOrganizationService service, Entity entity)</span></li> <li>        <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#2b91af">Guid</span><span style="background:#ffffff;color:#000000">&gt;();</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">service.BeginCreate(entity, (asyncResult) =&gt;</span></li> <li>            <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li>                <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">tcs.TrySetResult(((IOrganizationService)asyncResult.AsyncState).EndCreate(asyncResult));</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li>                <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">}, service);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li>        <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000"> Delete(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> IOrganizationService service, </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> entityName, System.</span><span style="background:#ffffff;color:#2b91af">Guid</span><span style="background:#ffffff;color:#000000"> id)</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000">&gt;();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000">service.BeginDelete(entityName, id, (asyncResult) =&gt;</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">{</span></li> <li>                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">{</span></li> <li>                    <span style="background:#ffffff;color:#000000">((IOrganizationService)asyncResult.AsyncState).EndDelete(asyncResult);</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">tcs.TrySetResult(</span><span style="background:#ffffff;color:#0000ff">null</span><span style="background:#ffffff;color:#000000">);</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li>                <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">}, service);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li>        <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000"> Disassociate(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> IOrganizationService service, </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> entityName, System.</span><span style="background:#ffffff;color:#2b91af">Guid</span><span style="background:#ffffff;color:#000000"> entityId, Relationship relationship, EntityReferenceCollection relatedEntities)</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000">&gt;();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000">service.BeginDisassociate(entityName, entityId, relationship, relatedEntities, (asyncResult) =&gt;</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">{</span></li> <li>                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">{</span></li> <li>                    <span style="background:#ffffff;color:#000000">((IOrganizationService)asyncResult.AsyncState).EndDisassociate(asyncResult);</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">tcs.TrySetResult(</span><span style="background:#ffffff;color:#0000ff">null</span><span style="background:#ffffff;color:#000000">);</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li>                <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">}, service);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li>        <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000">&lt;OrganizationResponse&gt; Execute(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> IOrganizationService service, OrganizationRequest request)</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;OrganizationResponse&gt;();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000">service.BeginExecute(request, (asyncResult) =&gt;</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">{</span></li> <li>                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">{</span></li> <li>                    <span style="background:#ffffff;color:#000000">tcs.TrySetResult(((IOrganizationService)asyncResult.AsyncState).EndExecute(asyncResult));</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">}</span></li> <li>                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">{</span></li> <li>                    <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">}</span></li> <li>            <span style="background:#ffffff;color:#000000">}, service);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000">&lt;Entity&gt; Retrieve(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> IOrganizationService service, </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> entityName, System.</span><span style="background:#ffffff;color:#2b91af">Guid</span><span style="background:#ffffff;color:#000000"> id, ColumnSet columnSet)</span></li> <li>        <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;Entity&gt;();</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">service.BeginRetrieve(entityName, id, columnSet, (asyncResult) =&gt;</span></li> <li>            <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li>                <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">tcs.TrySetResult(((IOrganizationService)asyncResult.AsyncState).EndRetrieve(asyncResult));</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li>                <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li>                <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">}, service);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li>        <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000">&lt;EntityCollection&gt; RetrieveMultiple(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> IOrganizationService service, QueryBase query)</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;EntityCollection&gt;();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000">service.BeginRetrieveMultiple(query, (asyncResult) =&gt;</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">{</span></li> <li>                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">{</span></li> <li>                    <span style="background:#ffffff;color:#000000">tcs.TrySetResult(((IOrganizationService)asyncResult.AsyncState).EndRetrieveMultiple(asyncResult));</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">}</span></li> <li>                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">{</span></li> <li>                    <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">}</span></li> <li>            <span style="background:#ffffff;color:#000000">}, service);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000"> Update(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> IOrganizationService service, Entity entity)</span></li> <li>        <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000">&gt;();</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000">service.BeginUpdate(entity, (asyncResult) =&gt;</span></li> <li>            <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li>                <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                    <span style="background:#ffffff;color:#000000">((IOrganizationService)asyncResult.AsyncState).EndUpdate(asyncResult);</span></li> <li>                    <span style="background:#ffffff;color:#000000">tcs.TrySetResult(</span><span style="background:#ffffff;color:#0000ff">null</span><span style="background:#ffffff;color:#000000">);</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">}</span></li> <li>                <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">{</span></li> <li>                    <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">}</span></li> <li>            <span style="background:#ffffff;color:#000000">}, service);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>&#160;</p>  <p><b>Using the New Features</b></p>  <p>Now that my project is setup, I can start using the new features to interact with CRM. Here’s the Silverlight example from above rewritten to take advantage of the new keywords:</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9cf89dac-da70-4126-ad0a-25427cc93be3" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">async</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> AsynchronousExample(</span><span style="background:#ffffff;color:#2b91af">IOrganizationService</span><span style="background:#ffffff;color:#000000"> service)</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Build the query</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> query = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">QueryExpression</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">EntityName = </span><span style="background:#ffffff;color:#a31515">&quot;contact&quot;</span><span style="background:#ffffff;color:#000000">,</span></li> <li>        <span style="background:#ffffff;color:#000000">ColumnSet = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ColumnSet</span><span style="background:#ffffff;color:#000000"> { Columns = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ObservableCollection</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000">&gt; { </span><span style="background:#ffffff;color:#a31515">&quot;fullname&quot;</span><span style="background:#ffffff;color:#000000"> } }</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">};</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Send it to the server and await the response</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> response = </span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> service.RetrieveMultiple(query);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">//Iterate across the results and output the fullname of each contact</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">foreach</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> contact </span><span style="background:#ffffff;color:#0000ff">in</span><span style="background:#ffffff;color:#000000"> response.Entities)</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">MessageBox</span><span style="background:#ffffff;color:#000000">.Show(contact.GetAttributeValue&lt;</span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000">&gt;(</span><span style="background:#ffffff;color:#a31515">&quot;fullname&quot;</span><span style="background:#ffffff;color:#000000">));</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>&#160;</p>  <p>There are several points to notice here. Firstly, notice the use of the async keyword in the method signature, this indicates that this method runs asynchronously and allows us to use the await keyword within the method body. The await keyword is used to await the results of the RetrieveMultiple extension method.</p>  <p>More interestingly though, there are several things to notice that are <b>not</b> here. Firstly, there no callbacks and all of the logic is defined within the same method body. This makes the code much more readable. Secondly, because execution is resumed on the UI thread when service.RetrieveMultiple returns a result, we do not have to dispatch back up to the UI to display the results to the user.</p>  <p>Also note there is nothing special required to invoke this method. Although the method is marked as asynchronous, the consuming code does not need to be aware of this:</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:89a2aaaa-298d-4e9f-be05-34da9363cdec" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> MainPage()</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000">InitializeComponent();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> service = </span><span style="background:#ffffff;color:#2b91af">SilverlightUtility</span><span style="background:#ffffff;color:#000000">.GetSoapService();</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">AsynchronousExample(service);</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p><b></b>&#160;</p>  <p><b>Under The Hood</b></p>  <p>So what’s going on in the extension method that we called? For a method to be awaitable, it needs to return one of three types; void, Task or Task&lt;T&gt;, so to await CRM web service calls we need to wrap the available methods up into a new method that returns an awaitable type. For example, this is the RetrieveMultiple extension method used in the previous example:</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:85ec23bc-dcb7-49cd-8154-265f19b37ecf" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#2b91af">EntityCollection</span><span style="background:#ffffff;color:#000000">&gt; RetrieveMultiple(</span><span style="background:#ffffff;color:#0000ff">this</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">IOrganizationService</span><span style="background:#ffffff;color:#000000"> service, </span><span style="background:#ffffff;color:#2b91af">QueryBase</span><span style="background:#ffffff;color:#000000"> query)</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> tcs = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">TaskCompletionSource</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#2b91af">EntityCollection</span><span style="background:#ffffff;color:#000000">&gt;();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000">service.BeginRetrieveMultiple(query, (asyncResult) =&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000">tcs.TrySetResult(((</span><span style="background:#ffffff;color:#2b91af">IOrganizationService</span><span style="background:#ffffff;color:#000000">)asyncResult.AsyncState).EndRetrieveMultiple(asyncResult));</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000"> ex)</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000">tcs.TrySetException(ex);</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>    <span style="background:#ffffff;color:#000000">}, service);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> tcs.Task;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>&#160;</p>  <p>The TaskCompletionSource&lt;T&gt; object is used to create a task of the appropriate type, which allows us to await the results of the standard BeginRetrieveMultiple method. Also note that error handling is also catered for, so if the web service throws an exception the awaiting code will be notified.</p>  <p><b>Some Considerations</b></p>  <p>This feature does require Visual Studio 2012, which is due for launch on September 12<sup>th</sup> 2012. Unfortunately, the excellent CRM 2011 Developer Toolkit does not currently work with Visual Studio 2012, which is worth bearing in mind if you’re contemplating a switch.</p>  <p>This feature also requires Silverlight 5. Silverlight 5 support within CRM is not straight forward; it is not supported when embedding directly on to forms, but wrapping your SL5 XAP resources inside an HTML web resource is supported.</p>  <p><b>Conclusion</b></p>  <p>So there we have it, the new async features in .NET 4.5 combined with the Async Targeting Pack provide Silverlight developers with the tools to transform their asynchronous code back to readable, maintainable methods, by removing the need to litter business logic with callbacks and UI dispatching code. We’ve seen how to install and use the basic features of the language enhancements, and have used a class of extension methods that enable us to work with the CRM WCF web service with the new async features.</p>  <p>Visual Studio 2012 RTM is now available to download on MSDN, and I would highly recommend taking a look!</p>  <table style="width: 400px;" cellspacing="0" cellpadding="2" border="0"><tbody>     <tr>       <td valign="top" width="117"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png"><img title="Dave Burman" style="margin-right: auto; margin-left: auto; float: none; display: block;" border="0" alt="Dave" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png" width="100" height="100" /></a></td>        <td valign="top" width="283">         <p><b><a href="https://blogs.msdn.com/b/thecrmguys/archive/tags/dave+burman/">Dave Burman</a></b>             <br />Consultant             <br />Microsoft Consulting Services UK</p>          <p><a href="https://blogs.msdn.com/b/thecrmguys/archive/2012/03/14/dave-burman.aspx">View my bio</a></p>       </td>     </tr>   </tbody></table>]]></content:encoded>
    </item>
    <item>
      <title>CRM Reporting and SQL 2012 AlwaysOn Availability Groups – Better Together</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/crm-reporting-and-sql-2012-alwayson-availability-groups-better-together</link>
      <pubDate>Fri, 10 Aug 2012 04:58:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2012/08/10/crm-reporting-and-sql-2012-alwayson-availability-groups-better-together/</guid>
      <description><![CDATA[The Problem
A common issue that I have come across in CRM deployments, particularly for Enterprise...]]></description>
      <content:encoded><![CDATA[<h1 style="text-align: left;"><span style="font-size: large;">The<strong> </strong>Problem</span><strong></strong></h1>
<p>A common issue that I have come across in CRM deployments, particularly for Enterprise customers, is deadlocking on the SQL server resulting in a degraded&nbsp;performance of our CRM environment.</p>
<p>I&rsquo;ve experienced severe impact of this deadlocking to the degree that other CRM SQL processes are aborted resulting in errors being presented to the user, or systems integrating with CRM fail to retrieve data &ndash; In the&nbsp;early stages of a project and especially post go live, this can have a crippling effect on the user adoption of the new deployment.</p>
<p>More often than not, in my experience, the deadlocks were a result of long running reports and integrations being executed against SQL that could ultimately be better managed.</p>
<p>Wouldn&rsquo;t it be nice if we could just offload these long running reports and redirect our integration to a second copy of our CRM data, so that we didn&rsquo;t impact user experience?</p>
<h2><span style="font-size: medium;">Previous<strong> </strong>Mitigation<strong> </strong>Options</span><strong></strong></h2>
<p>To date, I have come across two ways to offload our read only workloads such as reporting or integration (where CRM is the data master). One of these options, Transactional Replication, was always chosen as a last resort over the other, SQL Mirroring, due to some constraints.</p>
<p>If you are reading this post, I will assume you have some knowledge of SQL high availability options such as SQL Mirroring and SQL Transactional Replication. Additionally, this article will not focus on how to create reports so&nbsp;a working knowledge of writing reports using tools such as SQL Data Tools is assumed.</p>
<h3><span style="font-size: small;">SQL<strong> </strong>Mirroring</span><strong></strong></h3>
<p>This is a common option that I&rsquo;ve deployed a number of times. As you may know, SQL mirroring requires that the secondary instance database remains in a &lsquo;recovery&rsquo; state, thus rendering the database useless until you actually invoke DR or a manual failover. To&nbsp;overcome this need for the database to remain inaccessible, we would&nbsp; implement snapshot technology to produce essentially a 3<sup>rd </sup>copy of your data, this time in an accessible state which we can use to offload our workloads against.</p>
<p>This solution works well but comes with some limitations. For example, your report data would only be as up to date as your most recent snapshot and snapshots can take some time to produce, depending on the size of your database. Additionally, because we need to implement snapshots, you get yourself into a position where you&nbsp; need enough storage for the 3<sup>rd</sup> copy of your data. This probably isn&rsquo;t such an issue with the cost of disk nowadays but if you have a VERY large database, which takes a long time to snapshot and you need to run reports frequently, that would mean that you may need enough storage for a 4<sup>th</sup> copy of your database so that reports can&nbsp; continue to run against the 3<sup>rd</sup> whilst the 4<sup>th</sup> is generated.&nbsp;</p>
<h3><span style="font-size: small;">SQL<strong> </strong>Transactional<strong> </strong>Replication</span><strong></strong></h3>
<p>I pointed out that this option wouldn&rsquo;t be something I recommended in the past. This is due to the fact that replication is not officially supported by Microsoft, definitely not something you want to risk. The second problem is that replication depends on a stable schema, so if you did chose to&nbsp;deploy Transactional Replication due to up to date report data requirements, you would need to essentially break replication prior to the deployment of any CRM customizations and then re-establish replication post deployment.&nbsp;</p>
<p>This does add complexity and additional&nbsp;time to your deployment process but&nbsp;transactional replication does help you meet data requirements and provide for more up to date data than SQL Mirroring with Snapshots would - You just&nbsp;need to keep the trade-offs in mind during design and when trying to maintain supportability.</p>
<h2><span style="font-size: medium;">The<strong> </strong>Solution</span><strong></strong></h2>
<p>Enter SQL2012. SQL 2012 introduces AlwaysOn Availability Groups. - <a href="https://www.microsoft.com/sqlserver/en/us/solutions-technologies/mission-critical-operations/SQL-Server-2012-high-availability.aspx">https://www.microsoft.com/sqlserver/en/us/solutions-technologies/mission-critical-operations/SQL-Server-2012-high-availability.aspx</a></p>
<p>An Availability Group is essentially a host name that allows you to host a set of primary databases on a single primary replica, you can then host up to four secondary replicas that can be used as failover targets.</p>
<p>Availability Groups are in a way, similar to SQL Mirroring but one of the key differences that we leverage in this solution, is the fact the secondary instances (replicas) can remain in an accessible state. So with this capability and some configuration, we would be able to offload our CRM workloads against a secondary replica.&nbsp;</p>
<h3><span style="font-size: small;">Configuration</span><strong></strong></h3>
<h4><span style="font-size: small;">SQL<strong> </strong>Server<strong> </strong>AlwaysOn<strong> </strong>Availability<strong> </strong>Groups</span><strong></strong></h4>
<p>This blog won&rsquo;t focus too much on the configuration of SQL but there are some key points that you need to keep in mind.&nbsp;You would need to configure:</p>
<ol>
<li>A Availability Group Listener.</li>
<li>Secondary replicas that would host read only copies of your CRM Organization database.</li>
<li>Availability Group routing.</li>
</ol>
<p>The listener is essentially a DNS hostname that you would use when configuring your SQL Server Reporting Server (SSRS) data source connection and the routing tells SQL which secondary replica should handle the incoming connection, depending on whether the connection intent is read-only or read-write.</p>
<p>The trigger that tells SQL what the connection attempt is, is a new parameter within the SQL Native Client 11.0 called Application Intent. So in short, SQL will access all incoming connections on that hostname, access the connection and if it is read-only, route the connection to your secondary replica that you have provisioned for offloading workloads.</p>
<p>After you have created your Availability Group and configured routing, there is a very simple way to test that the routing is working.&nbsp;If you run the SQLCMD below (specifying the &ndash;K switch to imply &lsquo;ReadOnly&rsquo;) and select server name, you will notice that prior to configuring my routing, the connected server is my primary SQL server, &lsquo;APC-SQL1&rsquo;.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/8078.SQLCMD1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/8078.SQLCMD1.png"><img style="margin-right: auto; margin-left: auto; display: block;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/8078.SQLCMD1.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/8078.SQLCMD1.png" alt="" border="0" /></a>&nbsp;</p>
<p>Post routing configuration, if we were to run the same command, we would expect the connected server to be the secondary replica defined whilst creating your AG, as seen below.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/7002.SQLCMD2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/7002.SQLCMD2.png"><img style="margin-right: auto; margin-left: auto; display: block;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/7002.SQLCMD2.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/7002.SQLCMD2.png" alt="" border="0" /></a></p>
<h4><span style="font-size: small;">CRM &amp;<strong> </strong>SSRS</span><strong></strong></h4>
<p>Right, so we have tested that our Availability Group and associated routing is working correctly. If I now change roles and&nbsp;become&nbsp;a&nbsp;CRM&nbsp;administrator and the SQL guys had informed me that moving forward, I need to use some new parameters for the data source connection utilized by CRM reports, how would I go about implementing these parameters.</p>
<p>Before we go ahead with this section, we need to keep in mind, some limitations with offloading reports. These aren&rsquo;t new limitations when comparing to the previous options but worth thinking about.</p>
<ol>
<li>FetchXML reports cannot currently be offloaded due to the fact that they connect via web services. The hope is that in future releases of CRM, this will be configurable.</li>
<li>Related to the 1<sup>st</sup>, reports created through the CRM UI using report manager, are created by default in FetchXML format. As such, they would need to be recreated by administrators if you identify them as long running reports or that they are causing locking.</li>
<li>Out the Box reports are created using a special data source that lets SQL know which organization the report is being run against. Again, this is a report that would need to be recreated by administrators if desired.&nbsp;</li>
</ol>
<p>I have in my test environment, a very simple report created using SQL Data Tools that pulls a list of all accounts currently in CRM. During creation, this report was configured to use a custom data source.</p>
<p>To load this into CRM, we simply navigate to Workspace &gt; Reports and select New from the ribbon. I select to use an Existing File and navigate to my saved report, then click to&nbsp;Save and Close the form.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1882.SaveForm.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1882.SaveForm.png"><img style="margin-right: auto; margin-left: auto; display: block;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1882.SaveForm.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1882.SaveForm.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>Doing so will save the report in CRM and&nbsp;SQL Server Reporting Services under Home &gt; &lsquo;MyCRMorg&rsquo; &gt; Custom Reports. As mentioned above, the report was created to use a custom data source so the first thing I do is manage this report and change the data source to use a shared data source, in this case, I configure it use the data source in the root of my organization tree in SSRS.&nbsp;</p>
<p>If I were to now run this report from within CRM, the report would run as expected and return a list of my accounts. This is standard functionality where the data is being pulled out of our production CRM database, as shown in this very simple SQL Profile Trace.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/6663.TraceSQL1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/6663.TraceSQL1.png"><img style="margin-right: auto; margin-left: auto; display: block;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/6663.TraceSQL1.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/6663.TraceSQL1.png" alt="" border="0" /></a></p>
<p>What we want to do, is leverage the parameters given to us by our SQL guys to essentially offload our CRM reports to a copy of our CRM database. In order to achieve this, I modify the shared MSCRM_DataSource above, to use these new parameters.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/5481.Para.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/5481.Para.png"><img style="margin-right: auto; margin-left: auto; display: block;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/5481.Para.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/5481.Para.png" alt="" width="302" height="150" border="0" /></a></p>
<p>&nbsp;It is important at this stage, to note that the connection string contains two key parts used to connect to our AG secondary replica.</p>
<ol>
<li>Data Source = AO-TR. This is the listener that I created during setup of the Availability Group.</li>
<li>Application Intent = ReadOnly. There are two options for this switch, ReadOnly and ReadWrite. If we were to choose ReadWrite, SQL would simply route the connection to our primary instance. Because we choose ReadOnly, and have the necessary routing defined for the AG, SQL will route the connection to our secondary&nbsp; replica.</li>
</ol>
<p>Saving this off and rerunning the report, we can see that the select statement using SQL profiler no longer runs against the primary database, instead, it is being offloaded to our secondary replica for processing.&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/6646.TraceSQL2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/6646.TraceSQL2.png"><img style="margin-right: auto; margin-left: auto; display: block;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/6646.TraceSQL2.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/6646.TraceSQL2.png" alt="" border="0" /></a></p>
<h2><span style="font-size: large;">In<strong> </strong>Summary</span></h2>
<p>To summarize, we have seen how new functionality introduced in SQL Server 2012 can be leveraged to improve the system performance and&nbsp;user experience of CRM 2011. This functionality provides a way to balance the load on SQL Server for CRM.</p>
<p>I see this functionality as being&nbsp;key to how we improve the scalability and performance of CRM Infrastructure&nbsp;for on premise customers however, please be aware that support for this solution is currently non-existent. Always engage the Microsoft Support team before customizing any of the Dynamics CRM reporting components to ensure that your solution is valid.</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="120">
<p><span style="font-size: small;"><span style="font-family: Times New Roman;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2577.AdamCaulkett.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2577.AdamCaulkett.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2577.AdamCaulkett.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2577.AdamCaulkett.jpg" alt="" width="146" height="164" border="0" /></a></span></span></p>
</td>
<td valign="top" width="478">
<p style="color: #7f7f7f; font-size: 10pt;"><a href="https://blogs.msdn.com/b/thecrmguys/archive/tags/Adam+Caulkett/"><strong>Adam Caulkett</strong></a> <br /> Senior Consultant <br /> Microsoft Consulting Services UK</p>
<p style="color: #7f7f7f; font-size: 10pt;"><a href="https://www.linkedin.com/pub/adam-caulkett/2/1a1/b71" target="_blank">LinkedIn&nbsp;</a></p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>Adam Caulkett</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/adam-caulkett</link>
      <pubDate>Thu, 09 Aug 2012 05:21:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2012/08/09/adam-caulkett/</guid>
      <description><![CDATA[Hi Everyone!
In September 2011, I joined Microsoft as a Consultant within the Microsoft Consulting...]]></description>
      <content:encoded><![CDATA[<p><span size="3"><span face="Times New Roman">Hi Everyone!</span></span></p>
<p><span size="3"><span face="Times New Roman">In September 2011, I joined Microsoft as a Consultant within the Microsoft Consulting Services Dynamics CRM UK team. My primary focus is the design and implementation of Dynamics CRM Infrastructure supporting primarily Enterprise customers. </span></span><span size="3"><span face="Times New Roman">My roles since 2000 have ranged from a system engineer to consultant and support analyst roles across the Microsoft stack. Since 2008, my focus has turned to predominately CRM and dependent infrastructure such as&nbsp;Active Directory, SQL Server and SQL Server Reporting Services.</span></span></p>
<p><span size="3"><span face="Times New Roman">I hope to add value to your role by sharing my experiences whilst working on cutting edge deployments of CRM in the Enterprise.</span></span></p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="120" valign="top"><span style="font-size: small;" size="3"><span style="font-size: small;" size="3"><span style="font-family: Times New Roman;" face="Times New Roman"></span></span></span>
<p mce_keep="true"><span style="font-size: small;" size="3"><span style="font-family: Times New Roman;" face="Times New Roman"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2577.AdamCaulkett.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2577.AdamCaulkett.jpg"><img width="146" height="164" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2577.AdamCaulkett.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2577.AdamCaulkett.jpg" border="0" /></a></span></span><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1307.IanCrowPic.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1307.IanCrowPic.png"></a></p>
<span style="font-size: small;" size="3"><span style="font-family: Times New Roman;" face="Times New Roman"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2577.AdamCaulkett.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2577.AdamCaulkett.jpg"></a></span></span><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1307.IanCrowPic.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1307.IanCrowPic.png"></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1307.IanCrowPic.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1307.IanCrowPic.png"></a></td>
<td width="478" valign="top">
<p style="color: #7f7f7f; font-size: 10pt;"><a href="https://blogs.msdn.com/b/thecrmguys/archive/tags/Adam+Caulkett/"><strong>Adam Caulkett</strong></a> <br /> Senior Consultant <br /> Microsoft Consulting Services UK</p>
<p style="color: #7f7f7f; font-size: 10pt;"><a href="https://www.linkedin.com/pub/adam-caulkett/2/1a1/b71" target="_blank">LinkedIn&nbsp;</a></p>
</td>
</tr>
</tbody>
</table>
<p></p>
<p mce_keep="true"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1307.IanCrowPic.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1307.IanCrowPic.png"></a>&nbsp;</p>
<p></p>]]></content:encoded>
    </item>
    <item>
      <title>User Impersonation with Silverlight</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/user-impersonation-with-silverlight</link>
      <pubDate>Wed, 14 Mar 2012 14:30:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2012/03/14/user-impersonation-with-silverlight/</guid>
      <description><![CDATA[Sometimes it&rsquo;s useful for Dynamics CRM to think you&rsquo;re someone else. An administrator...]]></description>
      <content:encoded><![CDATA[<p>Sometimes it&rsquo;s useful for Dynamics CRM to think you&rsquo;re someone else. An administrator may wish to retrieve or alter data as if they were another user, or execute certain special commands on someone else&rsquo;s behalf. Developers using the Microsoft.Xrm.Sdk will find that implementing this functionality is quite straight forward, as it&rsquo;s <a href="https://msdn.microsoft.com/en-us/library/gg334744.aspx" target="_blank">built into the SDK assemblies</a>. However, when the SDK assemblies are unavailable (for example, in a Silverlight application), implementing this impersonation is more difficult.</p>
<p><strong>Using the SDK</strong></p>
<p>Developers using the Microsoft.Xrm.Sdk assembly have access to the OrganizationServiceProxy and CallerImpersonationScope classes. The former is a proxy class that acts as a local reference to the CRM Organization web service, and provides more functionality than directly referencing the service. One such feature is the ability to specify a CallerId when performing web service requests. When a value is given, CRM reacts as if the specified user were calling them, rather than the authenticated user. CallerImpersonationScope works in a similar way, although you pass an existing service reference into it rather than creating a new connection, which is more useful in plug-ins, for example.</p>
<div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:603dd175-4934-4203-9e68-ef562d569598" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">Code Snippet</div>
<div style="background: #ddd; max-height: 300px; overflow: auto;"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;" start="1">
<li><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> CreateAccount(<span style="color: #2b91af;">OrganizationServiceProxy</span> service)</li>
<li style="background: #f3f3f3;">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">var</span> account = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">Entity</span>(<span style="color: #a31515;">"account"</span>);</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;account[<span style="color: #a31515;">"name"</span>] = <span style="color: #a31515;">"SDK Impersonated Account"</span>;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">var</span> testUser1 = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">Guid</span>(<span style="color: #a31515;">"C29551F3-123D-E111-8463-00155D001003"</span>);</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;service.CallerId = testUser1;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">var</span> response = service.Create(account);</li>
<li style="background: #f3f3f3;">}</li>
</ol></div>
</div>
</div>
<p></p>
<p><strong>Silverlight applications</strong></p>
<p>Silverlight applications cannot reference the SDK assemblies. However, we can still achieve the same functionality using the organization service WCF endpoint. We can actually inject the CallerId parameter as a SOAP header before making a web service call, and CRM has some great built in functionality to accommodate this approach.</p>
<p>Another approach is to authenticate against the web service with another users credentials. There are a number of security risks associated with this approach, and it is generally a bad idea.</p>
<p>The following code demonstrates an example of this CallerId injection. Please note this example depends on classes introduced in <a href="https://msdn.microsoft.com/en-us/library/gg594452.aspx" target="_blank">this walkthrough</a>.</p>
<div style="border: 1px solid #000080; color: #000000; font-family: 'Courier New', courier, monospace; font-size: 10pt;">
<div style="background: #000080; padding: 2px 5px; color: #ffffff; font-family: verdana, tahoma, arial, sans-serif; font-weight: bold;">Code Snippet</div>
<div style="background: #dddddd; overflow: auto; max-height: 500px;"><ol style="background: #ffffff; margin: 0px 0px 0px 2.5em; padding: 0px 0px 0px 5px;">
<li><span style="color: #2b91af;">Guid</span> testUser1 = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">Guid</span>(<span style="color: #a31515;">"C29551F3-123D-E111-8463-00155D001003"</span>);</li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li><span style="color: #0000ff;">var</span> account1 = GetNewAccount(<span style="color: #a31515;">"account1"</span>);</li>
<li style="background: #f3f3f3;"><span style="color: #0000ff;">var</span> account2 = GetNewAccount(<span style="color: #a31515;">"account2"</span>);</li>
<li><span style="color: #0000ff;">var</span> account3 = GetNewAccount(<span style="color: #a31515;">"account3"</span>);</li>
<li style="background: #f3f3f3;"><span style="color: #0000ff;">var</span> account4 = GetNewAccount(<span style="color: #a31515;">"account4"</span>);</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;"><span style="color: #0000ff;">var</span> service = (<span style="color: #2b91af;">OrganizationServiceClient</span>)<span style="color: #2b91af;">SilverlightUtility</span>.GetSoapService();</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li style="background: #f3f3f3;"><span style="color: #008000;">//Create first account</span></li>
<li>service.CreateAsync(account1);</li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li><span style="color: #0000ff;">using</span> (<span style="color: #0000ff;">var</span> scope = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">OperationContextScope</span>(service.InnerChannel))</li>
<li style="background: #f3f3f3;">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp; <span style="color: #008000;">//Inject caller Id to SOAP header</span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">var</span> ns = <span style="color: #a31515;">"https://schemas.microsoft.com/xrm/2011/Contracts"</span>;</li>
<li>&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">var</span> userHeader = <span style="color: #2b91af;">MessageHeader</span>.CreateHeader(<span style="color: #a31515;">"CallerId"</span>, ns, testUser1);</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp; <span style="color: #2b91af;">OperationContext</span>.Current.OutgoingMessageHeaders.Add(userHeader);</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp; <span style="color: #008000;">//Create second account</span></li>
<li>&nbsp;&nbsp;&nbsp; service.CreateAsync(account2);</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp; <span style="color: #008000;">//Create third account within the same OperationContextScope to indicate </span></li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp; <span style="color: #008000;">//all operations within this using block are performed with impersonation</span></li>
<li>&nbsp;&nbsp;&nbsp; service.CreateAsync(account3);</li>
<li style="background: #f3f3f3;">}</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;"><span style="color: #008000;">//Create fourth account</span></li>
<li>service.CreateAsync(account4);</li>
</ol></div>
</div>
<p>&nbsp;</p>
<p>The use of OperationContextScope allows us to modify the header of each request sent to the CRM web service within the scope of the using block. To impersonate, we need to include the CallerId parameter. CRM interprets this parameter and executes messages on the specified user&rsquo;s behalf.</p>
<p><strong>The result</strong></p>
<p>So what does the impersonation look like in CRM? In the example, I&rsquo;m creating four entities. I&rsquo;ve omitted some of the initialization logic to keep the sample brief, but assume the entities are all identical Entity objects representing accounts, named account1, account2, account3, and account4.&nbsp; Accounts 2 and 3 are created within the scope of the OperationContextScope, and 1 and 4 are not. Also note I injected the systemuserid of Test User 1 as a SOAP header within the using block, and I&rsquo;ve not had to specify any additional usernames or passwords anywhere.</p>
<p>When I run the code, I authenticate against the service using my own account (Dave Burman in CRM). The four accounts are created as pictured below.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/1205.clip_image002_660BF1C2.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/1205.clip_5F00_image002_5F00_660BF1C2.jpg"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="clip_image002" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/2262.clip_image002_thumb_3A2B7806.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/2262.clip_5F00_image002_5F00_thumb_5F00_3A2B7806.jpg" width="799" height="173" /></a></p>
<p>Notice that the owner and created by fields are different for accounts 2 and 3. CRM has created these records almost as if I were authenticated as Test User 1. Almost, but not quite.&nbsp; Notice the Created By (Delegate) field is populated for those two records. CRM is aware I&rsquo;m impersonating a user, and notes down my user name in this field.</p>
<p><b>Security considerations</b></p>
<p>So, if we can impersonate other users, what&rsquo;s to stop a standard user impersonating a system administrator and retrieving data they wouldn&rsquo;t normally be able to see? Fortunately we have a way of preventing this, via the security role functionality built into CRM. The &ldquo;Act on Behalf of Another User&rdquo; privilege allows administrators to control who can impersonate other users. This is the only privilege set in the built in &ldquo;Delegate&rdquo; role, so assigning this role to a user or team will allow them to impersonate. The web service will return an error back to an authenticated client attempting impersonation without this privilege.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/6472.image_0616D8B3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/6472.image_5F00_0616D8B3.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/1777.image_thumb_43578D7A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/1777.image_5F00_thumb_5F00_43578D7A.png" width="832" height="677" /></a></p>
<p>However, the &ldquo;Act on Behalf of Another User&rdquo; privilege should be used with caution.&nbsp; Care must be taken to ensure impersonation does not inadvertantly give users the ability to access or modify data that they would not normally be able to. &nbsp;Whilst CRM does not allow users to gain new&nbsp;privileges&nbsp;via impersonation (e.g. a user who does not have Account read access will not be able to gain it by impersonating a user that does), privilege scope can be elevated using this method. &nbsp;For example, a user with user scope read access to Accounts could gain organization wide access by impersonating a user with this privilege (e.g. the system administrator).</p>
<p><b>Tidying it all up</b></p>
<p>Finally, the Silverlight example above works well, but the code becomes cumbersome where there&rsquo;s lots of impersonation happening.&nbsp; The CRM Guys have developed a class of extension methods to provide each of the web service proxy methods with an extra CallerId parameter, which can be downloaded <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/8640.Impersonation%20Extension%20Methods.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/8640.Impersonation-Extension-Methods.zip" target="_blank">here</a>. To use the class, simply drop the file into your Silverlight application, and alter it&rsquo;s namespace to match the namespace of your web service reference.</p>
<p>As an example, the Silverlight example above can then be rewritten as follows.</p>
<div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7397566b-e35d-4487-96bb-7aa25115f903" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;">Code Snippet</div>
<div style="background: #ddd; max-height: 400px; overflow: auto;"><ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;" start="1">
<li><span style="color: #2b91af;">Guid</span> testUser1 = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">Guid</span>(<span style="color: #a31515;">"C29551F3-123D-E111-8463-00155D001003"</span>);</li>
<li style="background: #f3f3f3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li><span style="color: #0000ff;">var</span> account1 = GetNewAccount(<span style="color: #a31515;">"account1"</span>);</li>
<li style="background: #f3f3f3;"><span style="color: #0000ff;">var</span> account2 = GetNewAccount(<span style="color: #a31515;">"account2"</span>);</li>
<li><span style="color: #0000ff;">var</span> account3 = GetNewAccount(<span style="color: #a31515;">"account3"</span>);</li>
<li style="background: #f3f3f3;"><span style="color: #0000ff;">var</span> account4 = GetNewAccount(<span style="color: #a31515;">"account4"</span>);</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3;"><span style="color: #0000ff;">var</span> service = (<span style="color: #2b91af;">OrganizationServiceClient</span>)<span style="color: #2b91af;">SilverlightUtility</span>.GetSoapService();</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li style="background: #f3f3f3;"><span style="color: #008000;">//Create first account</span></li>
<li>service.CreateAsync(account1);</li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li><span style="color: #008000;">//Create second account</span></li>
<li style="background: #f3f3f3;">service.CreateAsync(account2, testUser1);</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li style="background: #f3f3f3;"><span style="color: #008000;">//Create third account</span></li>
<li>service.CreateAsync(account3, testUser1);</li>
<li style="background: #f3f3f3;">&nbsp;</li>
<li><span style="color: #008000;">//Create fourth account</span></li>
<li style="background: #f3f3f3;">service.CreateAsync(account4);</li>
</ol></div>
</div>
</div>
<p><b></b>&nbsp;</p>
<p><b>Conclusion</b></p>
<p>This article has provided an overview of the impersonation functionality available to CRM developers interacting with the application&rsquo;s web services. We&rsquo;ve looked at a number of different implementation options, including scenarios where the CRM SDK assemblies are unavailable. We&rsquo;ve also looked at some of the built in features that CRM has to accommodate this functionality. Hopefully you&rsquo;ve found it useful.</p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="120">
<p mce_keep="true"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png"><img title="Dave Burman" border="0" alt="Dave" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png" width="100" height="100" /></a></p>
</td>
<td valign="top" width="478">
<p style="color: #7f7f7f; font-size: 10pt;"><span style="color: black; font-size: 14pt;"><b><a href="https://blogs.msdn.com/b/thecrmguys/archive/tags/dave+burman/">Dave Burman</a></b></span> <br />Consultant <br />Microsoft Consulting Services UK</p>
<p style="color: #7f7f7f; font-size: 10pt;"><a href="https://blogs.msdn.com/b/thecrmguys/archive/2012/03/14/dave-burman.aspx">View my bio</a></p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>Dave Burman</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/dave-burman</link>
      <pubDate>Wed, 14 Mar 2012 13:35:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2012/03/14/dave-burman/</guid>
      <description><![CDATA[I&rsquo;ve been developing software professionally since 2007.&nbsp; During this time, I&rsquo;ve...]]></description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been developing software professionally since 2007.&nbsp; During this time, I&rsquo;ve been fortunate enough to work on a huge variety of projects, whilst gaining exposure to most of the Microsoft development stack.&nbsp; I&rsquo;ve been working with Dynamics CRM since 2010 and thoroughly enjoy pushing the boundaries of the product on a daily basis.</p>
<p>I joined Microsoft in late 2011 as a CRM Development Consultant.&nbsp; My role involves helping our customers design and implement Dynamics CRM customizations in line with best practices, allowing them to really tailor their xRM applications to suit their business needs in a supportable and maintainable way.</p>
<p>&nbsp;</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="120">
<p mce_keep="true"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png"><img title="Dave Burman" border="0" alt="Dave" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0410.daveb_76266403.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0410.daveb_5F00_76266403.png" width="100" height="100" /></a></p>
</td>
<td valign="top" width="478">
<p style="font-size: 10pt; color: #7f7f7f;"><span style="font-size: 14pt; color: black;"><b>Dave Burman</b></span> <br />Consultant<br />Microsoft Consulting Services UK</p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>Dynamics CRM 2011 Demos - Faking Multiple Personas</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/dynamics-crm-2011-demos-faking-multiple-personas</link>
      <pubDate>Wed, 12 Oct 2011 06:33:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2011/10/12/dynamics-crm-2011-demos-faking-multiple-personas/</guid>
      <description><![CDATA[Here&rsquo;s a quick post on a little tip that I find useful when trying to show how the systems we...]]></description>
      <content:encoded><![CDATA[<p>Here&rsquo;s a quick post on a little tip that I find useful when trying to show how the systems we are building will actually work for the customer&hellip;</p>
<p>One of the key business benefits of a Dynamics CRM implementation is turning &lsquo;personal knowledge&rsquo; into &lsquo;corporate knowledge&rsquo; so that when one user does something another user can benefit from it.&nbsp; Trying to get this concept across on a single screen projected at the front of the room where you run everything as a single proposed user can be challenging, but unless you achieve it your audience may not have that light bulb moment.</p>
<p>What I&rsquo;ve found works pretty well is to run your demonstration from a single machine installation (Windows Server hosting SQL Server and Dynamics CRM), and then use Remote Desktop Connection to loop back into the same machine as a different user so that you can easily switch from one persona to another.&nbsp; By setting the desktop background and maybe the Windows colour scheme to something different you can help give a visual cue as to which demo persona you are now.</p>
<p>I can sense you rushing off to try it now, but you may quickly hit a few snags that you&rsquo;ll need to iron out.&nbsp; All of the instructions below relate to Windows Server 2008 R2, but can be applied to previous OSes as well.</p>
<h2>Enable remote access on server</h2>
<p>The full article on this can be found in the &lsquo;<a href="https://technet.microsoft.com/en-us/library/cc794832(WS.10).aspx">Enable Remote Desktop</a>&rsquo; TechNet article, but the quick version is&hellip;</p>
<p>Open up Server Manager and use the circled bits of the image below to enable access:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0160.RDP-Enable_17747BFF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0160.RDP_2D00_Enable_5F00_17747BFF.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="RDP Enable" border="0" alt="RDP Enable" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/3301.RDP-Enable_thumb_1838A81D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/3301.RDP_2D00_Enable_5F00_thumb_5F00_1838A81D.png" width="644" height="201" /></a></p>
<h2>Enable remote access for your personas</h2>
<p>Again we have a TechNet article &lsquo;<a href="https://technet.microsoft.com/en-us/library/cc758036(WS.10).aspx">Add users to the Remote Desktop Users group</a>&rsquo;, summarized as&hellip;</p>
<p>Open <em>Start-&gt;Administrative Tools-&gt;Active Directory Users and Computers</em></p>
<p>Navigate to the location shown below and add the relevant user accounts to the highlighted group:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/2843.Group-Add_651F50AF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/2843.Group_2D00_Add_5F00_651F50AF.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="Group Add" border="0" alt="Group Add" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/5383.Group-Add_thumb_688CFA25.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/5383.Group_2D00_Add_5F00_thumb_5F00_688CFA25.png" width="644" height="320" /></a></p>
<h2>Enable remote log on for your personas</h2>
<p>The personas will now be able to connect to the server, but because we&rsquo;re on a Domain Controller there&rsquo;s an extra setup you need for each user to allow them to logon to a desktop.</p>
<p>TechNet describes that in a way <a href="https://technet.microsoft.com/en-us/library/cc742817.aspx">here</a>, and our helpful summary is&hellip;</p>
<p>Open <em>Start-&gt;Run&hellip;-&gt;gpedit.msc</em></p>
<p>Navigate the location shown and again add the relevant user accounts to the highlighted item:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/2843.Policy-Add_7FF78889.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/2843.Policy_2D00_Add_5F00_7FF78889.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="Policy Add" border="0" alt="Policy Add" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/3264.Policy-Add_thumb_555BA7AC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/3264.Policy_2D00_Add_5F00_thumb_5F00_555BA7AC.png" width="644" height="321" /></a></p>
<h2>Connect!</h2>
<p>You should now be able to open and RDP connection to &lsquo;localhost&rsquo; and logon as one of your additional personas:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/7356.RDP_1DCF4167.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/7356.RDP_5F00_1DCF4167.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="RDP" border="0" alt="RDP" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/5224.RDP_thumb_33F536EC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/5224.RDP_5F00_thumb_5F00_33F536EC.png" width="320" height="364" /></a></p>
<p>Once logged in just set the background as normal.&nbsp; Then expand/collapse the Remote Desktop window and your audience should be able to keep track of who you are at any particular moment.</p>
<h2>Bonus scenario</h2>
<p>If you&rsquo;re wanting to run your demo by connecting to your Hyper-V guest partition from your parent partition then you can use Remote Desktop if you have a network route available.&nbsp; One great result of this is that you can then use Remote Desktop features like cut and paste, drive share, etc between parent and guest partitions.&nbsp; To make that work you&rsquo;ll need a suitable IP address on each partition, which you can do with a static address for an interface connected to the Hyper-V Internal Virtual Network.&nbsp; Configuring that is a post all of its own, so let us know if you need that info and we&rsquo;ll be sure to do one.</p>
<h1>Summary</h1>
<p>In this post we described three things you may need to do to allow you to Remote Desktop to your Dynamics Server to help demos run smoothly:</p>
<ol>
<li>Enable remote access to the server</li>
<li>Grant users remote desktop access</li>
<li>Grant users remote logon rights</li>
</ol>
<p>As ever thanks for reading and I hope you feel more informed.&nbsp; Please be sure to give your feedback on whether you like this type of content, and to ask any questions to help you and others understand the material better.</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="120">
<p mce_keep="true"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1307.IanCrowPic.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1307.IanCrowPic.png"><img title="IanCrow" border="0" alt="IanC" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1307.IanCrowPic.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/100x122/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1307.IanCrowPic.png" width="100" height="122" /></a></p>
</td>
<td valign="top" width="478">
<p style="color: #7f7f7f; font-size: 10pt;"><span style="color: black; font-size: 14pt;"><b><a href="https://blogs.msdn.com/b/thecrmguys/archive/tags/Ian+Crow/">Ian Crow</a></b></span> <br />Principal Consultant <br />Microsoft Consulting Services UK <br /><br /><a href="https://blogs.msdn.com/b/thecrmguys/archive/2011/09/07/ian-crow.aspx">View my bio</a></p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>Peter Simons</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/peter-simons</link>
      <pubDate>Mon, 19 Sep 2011 05:26:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2011/09/19/peter-simons/</guid>
      <description><![CDATA[After graduating from the University of Surrey in 1995 I initially worked in both software...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: tahoma,arial,helvetica,sans-serif; font-size: small;">After graduating from the University of Surrey in 1995 I initially worked in both software development and support roles until my first CRM project as a contractor on a UK wide Siebel implementation for Prudential Assurance starting in 1998. Since then I have continued my focus on CRM, moving into a permanent EMEA consulting role with Siebel Expert Services for approximately four years between 2002 and 2006 and then Microsoft Consulting Services from 2006 to date.</span></p>
<p><span style="font-family: tahoma,arial,helvetica,sans-serif; font-size: small;">In my role at Microsoft I have continued to deepen my CRM expertise whilst broadening into other technologies including roles on large scale Microsoft Exchange, BizTalk and SharePoint projects.</span></p>
<p><span style="font-family: tahoma,arial,helvetica,sans-serif; font-size: small;">My passion however still remains in the CRM and xRM space, using Microsoft Dynamics CRM to implement enterprise class solutions across many sectors including: Finance, Health, Education and other Government departments. Within this area my work is varied including: CRM Architecture; CRM business analysis and functional design; CRM Configuration; infrastructure design and performance optimization; and regular contributions / review of published CRM articles and methodologies including:</span></p>
<ul>
<li><a href="https://mbs.microsoft.com/partnersource/partneressentials/serviceplans/surestep">Dynamics Sure Step (Methodology): Infrastructure Cross Phase Process</a></li>
<li><a href="https://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=e76d8916-81a6-4330-90ae-b24f8263fff8">White Paper: SAMPLE - Performance and Scalability Assessment of Customer Implementation</a></li>
<li><a href="https://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=ba826cee-eddf-4d6e-842d-27fd654ed893">Optimizing and Maintaining Microsoft Dynamics CRM 4.0</a></li>
<li><a href="https://www.microsoft.com/downloads/details.aspx?FamilyId=4E077F9F-A712-4CDC-BDEF-FB9969E46F2B&amp;displaylang=en">Service Scheduling: Optimizations and Considerations</a></li>
<li><a href="https://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=e835c764-ae63-4876-87da-786464ee7269">Microsoft Dynamics CRM 3.0 Suggested Hardware for Deployments up to 250 Concurrent Users</a></li>
</ul>
<p><span style="font-family: tahoma,arial,helvetica,sans-serif; font-size: small;">In some projects both with Siebel and Dynamics CRM I have worked on the end to end solution design and delivery whilst in many cases I have had the pleasure of working with partner organizations in providing proactive advice and guidance and short term reviews. This combination has allowed me to work on over 100 Siebel implementations and more that 50 Dynamics CRM projects to date and looking forward to the next 50!</span></p>
<p>&nbsp;</p>
<table border="0" cellspacing="0" cellpadding="0" sizcache="2" sizset="0">
<tbody sizcache="2" sizset="0">
<tr>
<td valign="top" width="120">
<p mce_keep="true"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2625.PeterSimons.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2625.PeterSimons.jpg"><img style="border: 0px;" title="PeterSimons" alt="Peter" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/2625.PeterSimons.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/100x122/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/2625.PeterSimons.jpg" width="156" height="103" /></a></p>
</td>
<td valign="top" width="478">
<p style="font-size: 10pt; color: #7f7f7f;"><span style="font-size: 14pt; color: black;"><b>Peter Simons</b></span> <br />Principal Consultant <br />Microsoft Consulting Services UK</p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>Auditing and Table Partitions in Dynamics CRM 2011</title>
      <link>https://docs.microsoft.com/archive/blogs/thecrmguys/auditing-and-table-partitions-in-dynamics-crm-2011</link>
      <pubDate>Wed, 07 Sep 2011 02:13:00 GMT</pubDate>
      <dc:creator><![CDATA[The CRM Guys [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/thecrmguys/2011/09/07/auditing-and-table-partitions-in-dynamics-crm-2011/</guid>
      <description><![CDATA[In this article we&rsquo;ll be looking behind the scenes at how Dynamics CRM 2011&rsquo;s new audit...]]></description>
      <content:encoded><![CDATA[<p>In this article we&rsquo;ll be looking behind the scenes at how Dynamics CRM 2011&rsquo;s new audit logs are engineered to maintain performance, and explain why what looked like anomalous behaviour to one of our customers was actually working just fine.</p>
<p>If you&rsquo;ve been looking closely at how the auditing feature works you may have noticed that it makes use of Microsoft SQL Server&rsquo;s partitioning feature as a means of improving the scalability and performance of the audit logs while retaining the audit data in the organisation database.&nbsp; Specifically, the SDK article <a href="https://msdn.microsoft.com/en-us/library/gg309664.aspx">Auditing Feature Overview</a> says:</p>
<blockquote>
<p>&ldquo;For Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online servers that use Microsoft SQL Server Enterprise editions, auditing data is recorded over time (quarterly) in partitions. A partition is called an audit log in the Microsoft Dynamics CRM Web application. Partitions are not supported, and therefore, not used, on a Microsoft Dynamics CRM 2011server that is running Microsoft SQL Server Standard edition.&rdquo;</p>
</blockquote>
<p>General information about partitioning is described in the MSDN article <a href="https://msdn.microsoft.com/en-us/library/ms190787.aspx">Partitioned Table and Index Concepts</a>, and in more detail in the white paper &ldquo;<a href="https://download.microsoft.com/download/D/B/D/DBDE7972-1EB9-470A-BA18-58849DB3EB3B/PartTableAndIndexStrat.docx">Partitioned Table and Index Strategies Using SQL Server 2008</a>&rdquo;. It&rsquo;s well worth understanding these concepts if you have to design the database storage for applications using large data sets.&nbsp; For now we&rsquo;ll briefly explain that the audit data table is partitioned on a date column function that places each calendar quarter&rsquo;s data into a different partition, and each partition behaves like a &lsquo;mini table&rsquo; ensuring that audit operations aren&rsquo;t overly slowed by having to navigate a single ever growing table.</p>
<p>If you decompose that quote above you might think it means the following two things:</p>
<ul>
<li>If you are using SQL Server Enterprise edition partitioning will be in use.</li>
<li>If you are using SQL Server Standard edition partitioning will not be in use.</li>
</ul>
<p>So a customer was a bit surprised when they looked at a Dynamics CRM 2011 instance that was using SQL Server 2008 Standard Edition and saw this under Settings &ndash;&gt; System &ndash;&gt; Auditing &ndash;&gt; Audit Log Management:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/4745.image_652D242F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/4745.image_5F00_652D242F.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/0143.image_thumb_0E54BC6E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/0143.image_5F00_thumb_5F00_0E54BC6E.png" width="440" height="100" /></a></p>
<p>Surely this suggests that quarterly partitioning is in use on Standard Edition?&nbsp; Adding to their confusion even more was that if they then looked at the same screen on their SQL Server Enterprise Edition environment they saw only a single row (so no hint of partitions).&nbsp; It looks as if it works exactly the opposite way to that statement above!&nbsp; And that would be strange since Standard Edition just doesn&rsquo;t support partitioning.</p>
<p>So let&rsquo;s dig a bit deeper and see what is actually happening&hellip;</p>
<p>In order to get to the bottom of this we started by looking at what was happening on another SQL Server Enterprise Edition deployment.</p>
<p>First of all we ran a query on the tenant&rsquo;s database to see what partitions existed for the table that stores the auditing data, AuditBase.&nbsp; ContactBase is in there just as a control: it should have just the one storage partition.</p>
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;" id="codeSnippetWrapper">
<pre class="csharpcode"><span class="kwrd">select</span> t.name, p.partition_number
<span class="kwrd">from</span> sys.partitions p,sys.tables t
<span class="kwrd">where</span> t.object_id = p.object_id
<span class="kwrd">and</span> t.name <span class="kwrd">in</span> (<span class="str">'ContactBase'</span>,<span class="str">'AuditBase'</span>)
<span class="kwrd">and</span> p.index_id <span class="kwrd">in</span> (0,1)</pre>
</div>
<p>Here&rsquo;s what we saw:</p>
<table style="width: 200px;" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="87">
<p>name</p>
</td>
<td valign="top" width="111">
<p>partition_number</p>
</td>
</tr>
<tr>
<td valign="top" width="87">
<p>ContactBase</p>
</td>
<td valign="top" width="111">
<p>1</p>
</td>
</tr>
<tr>
<td valign="top" width="87">
<p>AuditBase</p>
</td>
<td valign="top" width="111">
<p>1</p>
</td>
</tr>
<tr>
<td valign="top" width="87">
<p>AuditBase</p>
</td>
<td valign="top" width="111">
<p>2</p>
</td>
</tr>
<tr>
<td valign="top" width="87">
<p>AuditBase</p>
</td>
<td valign="top" width="111">
<p>4</p>
</td>
</tr>
<tr>
<td valign="top" width="87">
<p>AuditBase</p>
</td>
<td valign="top" width="127">
<p>3</p>
</td>
</tr>
</tbody>
</table>
<p>So it looks as if on Enterprise we can have partitioning working, which starts to disprove the idea that it never works.</p>
<p>Next we turned SQL Server Profiler on while refreshing the Audit Log grid, and see that this query is executed:</p>
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;" id="codeSnippetWrapper">
<pre class="csharpcode"><span class="kwrd">IF</span> (<span class="kwrd">CONVERT</span>(<span class="kwrd">int</span>, (<span class="kwrd">SELECT</span> SERVERPROPERTY(<span class="str">'EngineEdition'</span>))) = 3) <span class="kwrd">BEGIN</span>
<span class="kwrd">SELECT</span> partition_number <span class="kwrd">AS</span> <span class="str">'PartitionNumber'</span>, prv.<span class="kwrd">value</span> <span class="kwrd">AS</span> <span class="str">'End Date'</span>, used_page_count*8 <span class="kwrd">AS</span> <span class="str">'Size in KB'</span>
<span class="kwrd">FROM</span> sys.dm_db_partition_statspst <span class="kwrd">LEFT</span> <span class="kwrd">OUTER</span> <span class="kwrd">JOIN</span> sys.partition_range_values prv <span class="kwrd">ON</span> prv.boundary_id = pst.partition_number
<span class="kwrd">WHERE</span> object_id = object_id(<span class="str">'AuditBase'</span>) <span class="kwrd">AND</span> index_id <span class="kwrd">in</span> (0,1)
<span class="kwrd">END</span> <span class="kwrd">ELSE</span> <span class="kwrd">BEGIN</span>
<span class="kwrd">SELECT</span> DATENAME(qq, CreatedOn) <span class="kwrd">AS</span> <span class="str">'Quarter'</span>, <span class="kwrd">YEAR</span>(CreatedOn) <span class="kwrd">AS</span> <span class="str">'Year'</span>, <span class="kwrd">COUNT</span>(*) <span class="kwrd">AS</span> <span class="str">'Rows'</span>
<span class="kwrd">FROM</span> AuditBase
<span class="kwrd">GROUP</span> <span class="kwrd">BY</span> DATENAME(qq, CreatedOn), <span class="kwrd">YEAR</span>(CreatedOn)
<span class="kwrd">END</span></pre>
</div>
<p>Now we start to see what is really happening.&nbsp; The Dynamics CRM platform is executing a query that will return results that look similar, but are critically different, based on the edition of SQL Server Database Engine that is in use.</p>
<p>The <a href="https://msdn.microsoft.com/en-us/library/ms174396.aspx">SERVERPROPERTY</a> documentation tells us that the value 3 indicates Enterprise Edition.&nbsp; If this is detected then the result set consists of information about each physical partition, including the storage size in kilobytes.</p>
<p>For other editions (such as Standard) the actual AuditBase table is queried to group the data it contains by calendar quarter, and the number of rows in each quarter is calculated.</p>
<p>So we can now explain why the Standard Edition gave the illusion of having partitioning in use.&nbsp; The grid isn&rsquo;t showing partition data, but the results of a GROUP BY query that looks very similar.</p>
<p>This gives us a hint that although Dynamics CRM is gathering information to be able to show a set of quarterly results in the grid in both cases there will be a subtle difference in the last column: one will be a size and the other a number of rows.&nbsp; Sure enough if we compare what we see in Dynamics CRM for the Standard Edition above with what we see for Enterprise Edition we have &lsquo;Rows&rsquo; in one and &lsquo;KB&rsquo; in the other:</p>
<p><span style="font-family: 'Calibri','sans-serif'; color: #1f497d; font-size: 11pt; mso-fareast-font-family: 'MS Mincho'; mso-fareast-theme-font: minor-fareast; mso-ansi-language: en-gb; mso-fareast-language: ja; mso-bidi-language: ar-sa;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/6472.clip_image002_631575AD.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/6472.clip_5F00_image002_5F00_631575AD.jpg"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image002" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/metablogapi/7450.clip_image002_thumb_212E905F.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78-metablogapi/7450.clip_5F00_image002_5F00_thumb_5F00_212E905F.jpg" width="510" height="118" v:shapes="_x0000_i1025" /></a></span></p>
<p>One mystery remains.&nbsp; If the Dynamics CRM gives a set of rows on both Standard and Enterprise why could the customer see only a single row on their Enterprise environment, suggesting that partitioning is not in place?</p>
<p>Well it turns out that partitioning is indeed missing from their environment.&nbsp; This had happened because a backup of an organisation database had been taken from a Standard Edition deployment and redeployed to Enterprise Edition.&nbsp; We already have KB articles describing that the partition information isn&rsquo;t &lsquo;magically&rsquo; fixed when redeploying from Enterprise to Standard and so has to be removed prior to the backup on the source deployment.&nbsp; See <a href="https://support.microsoft.com/kb/2567984">KB2567984</a> for example.</p>
<p>The opposite is also true: when moving from Standard to Enterprise the overall redeployment operation works but you don&rsquo;t get partitions applied to AuditBase.&nbsp; However, the EngineEdition in the query above will now be Enterprise, so you get a single row describing the non-partitioned table and not the set of &lsquo;fake&rsquo; partition rows that you would have seen (for the same database) on Standard Edition.</p>
<p>The bad news here is that in turn you lose the ability to be able to delete just a portion of the audit log, and you obviously can&rsquo;t delete the active storage unit.&nbsp; So its important that you clear down any aged log data that you don&rsquo;t want in the source Standard Edition deployment, and then potentially add the partitioning behaviour to AuditBase in the Enterprise Edition.&nbsp; I haven&rsquo;t found the correct way to do that last task yet, but will try to do so and add a follow-up post.</p>
<h1>Summary</h1>
<p>In this post we established that:</p>
<ol>
<li>Table partitioning is only used on SQL Server Enterprise Edition, and separates the data into quarterly &lsquo;chunks&rsquo; for management (i.e. deletion)</li>
<li>Dynamics CRM &lsquo;fakes&rsquo; a similar set of data on Standard Edition using a GROUP BY clause on the unpartitioned data</li>
<li>Restoring organisation databases across SQL Server editions can lead to complications</li>
</ol>
<p>Thanks for reading and I hope you feel more informed.&nbsp; Please be sure to give your feedback on whether you like this type of content, and to ask any questions to help you and others understand the material better.</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="120">
<p mce_keep="true"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1307.IanCrowPic.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1307.IanCrowPic.png"><img title="IanCrow" border="0" alt="IanC" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/78/1307.IanCrowPic.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/100x122/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-78/1307.IanCrowPic.png" width="100" height="122" /></a></p>
</td>
<td valign="top" width="478">
<p style="color: #7f7f7f; font-size: 10pt;"><span style="color: black; font-size: 14pt;"><b><a href="https://blogs.msdn.com/b/thecrmguys/archive/tags/Ian+Crow/">Ian Crow</a></b></span> <br />Principal Consultant <br />Microsoft Consulting Services UK <br /><br /><a href="https://blogs.msdn.com/b/thecrmguys/archive/2011/09/07/ian-crow.aspx">View my bio</a></p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
  </channel>
</rss>