<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.microsoft.co.il/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Offir Shvartz</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/</link><description>We code with love or we code not...</description><dc:language>en</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><item><title>AppFabric Caching Service Using SSL</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2013/02/01/appfabric-caching-service-using-ssl.aspx</link><pubDate>Fri, 01 Feb 2013 12:50:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:1721211</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=1721211</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2013/02/01/appfabric-caching-service-using-ssl.aspx#comments</comments><description>&lt;p&gt;I really like AppFabric distributed cache (previously called Velocity). It’s so simple to use and it has really strong features like notification based local cache. It basically has two versions, one is targeting for on premise and one is for the cloud (Azure). The API is similar which makes it very easy to move your application in later phases to the cloud. But back to my customer which security was a strong requirement because of the nature of his system which I won’t mention here but I’m sure you get the idea. His security requirements are that &lt;b&gt;&lt;u&gt;all connection between machines will be sign and encrypted using a given certificate.&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;App Fabric Caching Security mode&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;When looking for information regarding AppFabric security model you find only few pages (like &lt;a href="http://msdn.microsoft.com/en-us/library/ff718179.aspx"&gt;this)&lt;/a&gt; that says that AppFabirc Cache is secured in transport level by default and you can choose whether you want to enable encryption and signing (they are enabled by default) but I also found bunch of Stackoverflow question that wanted to understand more regarding how the security is implemented&amp;nbsp; like &lt;a href="http://stackoverflow.com/questions/6242764/security-in-appfabric-caching"&gt;this&lt;/a&gt; and &lt;a href="http://stackoverflow.com/questions/4974845/appfabric-caching-transport-security"&gt;this&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;To conclude both of the posts they say that app fabric transport relay on WCF – the binding protocol is TCP and the security is similar to &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.windowsstreamsecuritybindingelement.aspx"&gt;WindowsStreamSecurityBinding&lt;/a&gt; which means the encryption and signing using the windows identity token. unfortunately This security model is not sufficient for my client so…&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Try #1– Microsoft Support&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;It sounded to me like a reasonable request to extend/control the security model and it should be simple considering the fact that as far as I understand the communication relay on WCF. so we tried Microsoft support and this is what Microsoft answered: &lt;/p&gt;  &lt;p&gt;&lt;i&gt;“Following our discussion last week, I contacted our developers to confirm if AppFabric caching has a feature to extend or there’s any provider which allows to change binding for communication between cache client and caching service i.e. from NetTcpBinding to BasicHttpBinding or WsHttpBinding to use SSL. As discussed earlier, there’s NO feature or provider which allows this. So, it leaves only two security options to be set on the cache cluster: None and Transport (default being Transport with Encrypt and Sign).”&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;dead end &lt;img src="http://blogs.microsoft.co.il/blogs/oshvartz/wlEmoticon-sadsmile_43E66704.png" class="wlEmoticon wlEmoticon-sadsmile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Sad smile" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Try #2 – let’s look inside&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;As a last resort I decides looking inside the code. It’s a longshot but still AppFabic is written in .NET meaning you can use decompiler tool to look at the code. I use &lt;a href="http://www.jetbrains.com/decompiler/" target="_blank"&gt;DotPeek&lt;/a&gt; which is nice, gives great navigation functionality and most important free.This is what I learned:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;DistributedCachingService code has some implementations parts specific for azure meaning that it could be that the same code is used in Azure caching which is very nice in my opinion allowing system that use the cache to move easily to the cloud and change only the configuration. &lt;/li&gt;    &lt;li&gt;DataCacheSection– when browsing them I discovered the configuration section has exactly what I needed – SSL &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The Element AdvanceProperty contains ServerSecurityProperty this is how it looks:&lt;/p&gt;  &lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;height:227px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:105.72%;background-color:#f4f4f4;"&gt;   &lt;pre id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#008000;"&gt;// Type: Microsoft.ApplicationServer.Caching.ServerSecurityProperties&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Assembly: Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Assembly location: C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\ref\Caching\Microsoft.ApplicationServer.Caching.Core.dll&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Configuration;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; Microsoft.ApplicationServer.Caching&lt;br /&gt;{&lt;br /&gt;  [Serializable]&lt;br /&gt;  &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ServerSecurityProperties : ConfigurationElement, ISerializable&lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; MODE = &lt;span style="color:#006080;"&gt;&amp;quot;mode&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; PROTECTION_LEVEL = &lt;span style="color:#006080;"&gt;&amp;quot;protectionLevel&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; AUTHORIZATION = &lt;span style="color:#006080;"&gt;&amp;quot;authorization&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; ALLOW = &lt;span style="color:#006080;"&gt;&amp;quot;allow&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; SERVER_ACS_PROPERTIES = &lt;span style="color:#006080;"&gt;&amp;quot;serverAcs&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; USE_ACS_FOR_CLIENT = &lt;span style="color:#006080;"&gt;&amp;quot;useAcsForClient&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; SHARED_KEY_AUTH = &lt;span style="color:#006080;"&gt;&amp;quot;sharedKeyAuth&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; SSL_ENABLED = &lt;span style="color:#006080;"&gt;&amp;quot;sslEnabled&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; SSL_PROPERTIES = &lt;span style="color:#006080;"&gt;&amp;quot;sslProperties&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    [ConfigurationProperty(&lt;span style="color:#006080;"&gt;&amp;quot;mode&amp;quot;&lt;/span&gt;, DefaultValue = DataCacheSecurityMode.Transport)]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DataCacheSecurityMode DataCacheSecurityMode&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (DataCacheSecurityMode) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;mode&amp;quot;&lt;/span&gt;];&lt;br /&gt;      }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;mode&amp;quot;&lt;/span&gt;] = (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [ConfigurationProperty(&lt;span style="color:#006080;"&gt;&amp;quot;protectionLevel&amp;quot;&lt;/span&gt;, DefaultValue = DataCacheProtectionLevel.EncryptAndSign)]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DataCacheProtectionLevel DataCacheProtectionLevel&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (DataCacheProtectionLevel) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;protectionLevel&amp;quot;&lt;/span&gt;];&lt;br /&gt;      }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;protectionLevel&amp;quot;&lt;/span&gt;] = (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [ConfigurationCollection(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (AuthorizationElement), AddItemName = &lt;span style="color:#006080;"&gt;&amp;quot;allow&amp;quot;&lt;/span&gt;)]&lt;br /&gt;    [ConfigurationProperty(&lt;span style="color:#006080;"&gt;&amp;quot;authorization&amp;quot;&lt;/span&gt;, IsDefaultCollection = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;, IsRequired = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; AuthorizationElement Authorization&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (AuthorizationElement) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;authorization&amp;quot;&lt;/span&gt;];&lt;br /&gt;      }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;authorization&amp;quot;&lt;/span&gt;] = (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [ConfigurationProperty(&lt;span style="color:#006080;"&gt;&amp;quot;serverAcs&amp;quot;&lt;/span&gt;, IsDefaultCollection = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;, IsRequired = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ServerAcsSecurityElement AcsSecurity&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (ServerAcsSecurityElement) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;serverAcs&amp;quot;&lt;/span&gt;];&lt;br /&gt;      }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;serverAcs&amp;quot;&lt;/span&gt;] = (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [ConfigurationProperty(&lt;span style="color:#006080;"&gt;&amp;quot;useAcsForClient&amp;quot;&lt;/span&gt;, DefaultValue = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; UseAcsForClient&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;useAcsForClient&amp;quot;&lt;/span&gt;];&lt;br /&gt;      }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;useAcsForClient&amp;quot;&lt;/span&gt;] = (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) (&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;) (&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; ? 1 : 0);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [ConfigurationProperty(&lt;span style="color:#006080;"&gt;&amp;quot;sharedKeyAuth&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; SharedKeyAuthorization SharedKeyAuth&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (SharedKeyAuthorization) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;sharedKeyAuth&amp;quot;&lt;/span&gt;];&lt;br /&gt;      }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;sharedKeyAuth&amp;quot;&lt;/span&gt;] = (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [ConfigurationProperty(&lt;span style="color:#006080;"&gt;&amp;quot;sslEnabled&amp;quot;&lt;/span&gt;, DefaultValue = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;, IsRequired = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; SslEnabled&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;sslEnabled&amp;quot;&lt;/span&gt;];&lt;br /&gt;      }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;sslEnabled&amp;quot;&lt;/span&gt;] = (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) (&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;) (&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; ? 1 : 0);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [ConfigurationProperty(&lt;span style="color:#006080;"&gt;&amp;quot;sslProperties&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; SslProperties SslProperties&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (SslProperties) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;sslProperties&amp;quot;&lt;/span&gt;];&lt;br /&gt;      }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color:#006080;"&gt;&amp;quot;sslProperties&amp;quot;&lt;/span&gt;] = (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; ServerSecurityProperties()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; ServerSecurityProperties(SerializationInfo info, StreamingContext context)&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DataCacheSecurityMode = (DataCacheSecurityMode) info.GetValue(&lt;span style="color:#006080;"&gt;&amp;quot;mode&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (DataCacheSecurityMode));&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DataCacheProtectionLevel = (DataCacheProtectionLevel) info.GetValue(&lt;span style="color:#006080;"&gt;&amp;quot;protectionLevel&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (DataCacheProtectionLevel));&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Authorization = (AuthorizationElement) info.GetValue(&lt;span style="color:#006080;"&gt;&amp;quot;authorization&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (AuthorizationElement));&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.AcsSecurity = (ServerAcsSecurityElement) info.GetValue(&lt;span style="color:#006080;"&gt;&amp;quot;serverAcs&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (ServerAcsSecurityElement));&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.UseAcsForClient = (&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;) info.GetValue(&lt;span style="color:#006080;"&gt;&amp;quot;useAcsForClient&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;));&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SharedKeyAuth = (SharedKeyAuthorization) info.GetValue(&lt;span style="color:#006080;"&gt;&amp;quot;sharedKeyAuth&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (SharedKeyAuthorization));&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (SerializationException ex)&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.UseAcsForClient = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SharedKeyAuth = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SharedKeyAuthorization();&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SslProperties = (SslProperties) info.GetValue(&lt;span style="color:#006080;"&gt;&amp;quot;sslProperties&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (SslProperties));&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SslEnabled = info.GetBoolean(&lt;span style="color:#006080;"&gt;&amp;quot;sslEnabled&amp;quot;&lt;/span&gt;);&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (SerializationException ex)&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SslEnabled = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; DataCacheSecurity GetDataCacheSecurity()&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DataCacheSecurity(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; GetObjectData(SerializationInfo info, StreamingContext context)&lt;br /&gt;    {&lt;br /&gt;      info.AddValue(&lt;span style="color:#006080;"&gt;&amp;quot;mode&amp;quot;&lt;/span&gt;, (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DataCacheSecurityMode);&lt;br /&gt;      info.AddValue(&lt;span style="color:#006080;"&gt;&amp;quot;protectionLevel&amp;quot;&lt;/span&gt;, (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DataCacheProtectionLevel);&lt;br /&gt;      info.AddValue(&lt;span style="color:#006080;"&gt;&amp;quot;authorization&amp;quot;&lt;/span&gt;, (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Authorization);&lt;br /&gt;      info.AddValue(&lt;span style="color:#006080;"&gt;&amp;quot;serverAcs&amp;quot;&lt;/span&gt;, (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.AcsSecurity);&lt;br /&gt;      info.AddValue(&lt;span style="color:#006080;"&gt;&amp;quot;useAcsForClient&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.UseAcsForClient);&lt;br /&gt;      info.AddValue(&lt;span style="color:#006080;"&gt;&amp;quot;sharedKeyAuth&amp;quot;&lt;/span&gt;, (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SharedKeyAuth);&lt;br /&gt;      info.AddValue(&lt;span style="color:#006080;"&gt;&amp;quot;sslEnabled&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SslEnabled);&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SslEnabled)&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;      info.AddValue(&lt;span style="color:#006080;"&gt;&amp;quot;sslProperties&amp;quot;&lt;/span&gt;, (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.SslProperties);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;As you can see it has SSL enabled property and SSLProperties which include &amp;quot;certificateSubject”. So I tried setting this values with a legal certificate and the service worked &lt;img src="http://blogs.microsoft.co.il/blogs/oshvartz/wlEmoticon-smile_0C9FDFC9.png" class="wlEmoticon wlEmoticon-smile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Smile" /&gt;. But I celebrated too early because when drilling down to the usage of this property I discovered two things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The communication channel&amp;nbsp; relays on WCF: the type WcfTransportChannel with two derives WcfClientChannel and WcfServerChannel – I learned exactly the binding that is used: &lt;/li&gt;
&lt;/ul&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;pre id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SetupBindings()&lt;br /&gt;   {&lt;br /&gt;     BinaryMessageEncodingBindingElement encodingBindingElement = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; BinaryMessageEncodingBindingElement();&lt;br /&gt;     XmlDictionaryReaderQuotas.Max.CopyTo(encodingBindingElement.ReaderQuotas);&lt;br /&gt;     TcpTransportBindingElement transportBindingElement = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.PrepareTcpTransportBindingElement();&lt;br /&gt;     BindingElementCollection bindingCollection = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; BindingElementCollection();&lt;br /&gt;     bindingCollection.Add((BindingElement) encodingBindingElement);&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.AddSecurityBinding(bindingCollection);&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.AddCustomBindingElements(bindingCollection);&lt;br /&gt;     bindingCollection.Add((BindingElement) transportBindingElement);&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._tcpBinding = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CustomBinding((IEnumerable&amp;lt;BindingElement&amp;gt;) bindingCollection);&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._pipeBinding = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; NetNamedPipeBinding();&lt;br /&gt;   }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;In security aspect certificate is &lt;b&gt;ignored&lt;/b&gt; when using transport mode meaning the fact you can put it in configuration (SSLEnabled=”true”) file doesn’t mean it will really use SSL. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the code from the server side:&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;pre id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; AddSecurityBinding(BindingElementCollection bindingCollection)&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DataCacheSecurity.SecurityMode == DataCacheSecurityMode.Transport)&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._securityBindingElement = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; VelocityStreamSecurityBindingElement(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._serviceConfigurationManager, &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;);&lt;br /&gt;        bindingCollection.Add((BindingElement) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._securityBindingElement);&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._sslEnabled)&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;        bindingCollection.Add((BindingElement) &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SslStreamSecurityBindingElement()&lt;br /&gt;        {&lt;br /&gt;          RequireClientCertificate = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;&lt;br /&gt;        });&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; sslCertIdentity = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._serviceConfigurationManager.AdvancedProperties.SecurityProperties.SslProperties.SslCertIdentity;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; certificateCount = WcfServerChannel.GetCertificateCount(sslCertIdentity);&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (certificateCount == 0 &amp;amp;&amp;amp; Provider.IsEnabled(TraceLevel.Error))&lt;br /&gt;          EventLogWriter.WriteError(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._logSource, &lt;span style="color:#006080;"&gt;&amp;quot;Certificate with name {0} doesn&amp;#39;t exist&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[1]&lt;br /&gt;          {&lt;br /&gt;            (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) sslCertIdentity&lt;br /&gt;          });&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (certificateCount &amp;gt; 1 &amp;amp;&amp;amp; Provider.IsEnabled(TraceLevel.Error))&lt;br /&gt;          EventLogWriter.WriteError(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._logSource, &lt;span style="color:#006080;"&gt;&amp;quot;More than one certificate with the name {0} exist.&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[1]&lt;br /&gt;          {&lt;br /&gt;            (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) sslCertIdentity&lt;br /&gt;          });&lt;br /&gt;        ServiceCredentials serviceCredentials = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ServiceCredentials();&lt;br /&gt;        serviceCredentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectDistinguishedName, (&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) sslCertIdentity);&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._listenerParameters.Add((&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;) serviceCredentials);&lt;br /&gt;      }&lt;br /&gt;    }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;




&lt;ul&gt;
  &lt;li&gt;The cannel type the client uses is IDuplexSessionChannel – from WcfClientChannel ctor:&lt;/li&gt;
&lt;/ul&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;pre id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._tcpFactory = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._tcpBinding.BuildChannelFactory&amp;lt;IDuplexSessionChannel&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[0]);&lt;/pre&gt;

  &lt;/div&gt;

&lt;p&gt;So I learn a lot but unfortunately I didn’t find a way to override the current binding and security methods. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;The Solution&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;I was really frustrated at this point but then I remembered one of the new features of WCF 4 was Routing Service which one of his target scenarios are: Protocol bridging (“You receive messages over one transport protocol, and the destination endpoint uses a different protocol” – MSDN). the only thing you should know is exactly what is your binding to do the routing correctly and here is the full solution:&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/image_781D20FB.png"&gt;&lt;img src="http://blogs.microsoft.co.il/blogs/oshvartz/image_thumb_3B87B30F.png" title="image" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" alt="image" border="0" height="191" width="448" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Host Routing Service in the client side that listen to App Fabric request meaning: 
    &lt;ul&gt;
      &lt;li&gt;Implement the contract IDuplexSessionRouter &lt;/li&gt;

      &lt;li&gt;Has custom binding with: TcpTransport,BinaryMessageEncounding and windowsStreamSecurity &lt;/li&gt;

      &lt;li&gt;Route all communication using “MatchAll” Filter to the target Routing Service at the App Fabric Server&amp;nbsp; with the required binding/security (Transport security using certificate) &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;Host Routing Service In the AppFabric cache Server machine 
    &lt;ul&gt;
      &lt;li&gt;Implement the contract IDuplexSessionRouter &lt;/li&gt;

      &lt;li&gt;Has matching binding to the target service of the other router &lt;/li&gt;

      &lt;li&gt;Route all communication using “MatchAll” Filter to the App Fabric Server using custom bindingbinding with: TcpTransport,BinaryMessageEncounding and windowsStreamSecurity &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well it works &lt;img src="http://blogs.microsoft.co.il/blogs/oshvartz/wlEmoticon-openmouthedsmile_1D3F8CCA.png" class="wlEmoticon wlEmoticon-openmouthedsmile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Open-mouthed smile" /&gt; the client is agnostic to the fact that the messages are going through the routing services – the only down side is the double hopes the messages does but it doesn’t open the soap message (doesn’t Serialize /Deserialize) so I guess this solution it’s not bad.&lt;/p&gt;

&lt;p&gt;That’s all for now&lt;/p&gt;

&lt;p&gt;Cheers Offir&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=1721211" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/AppFabric/default.aspx">AppFabric</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Distrebuted+Cache/default.aspx">Distrebuted Cache</category></item><item><title>Azure Table Storage – limitations and solutions/workarounds(Part 2)</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/09/19/azure-table-storage-limitations-and-solutions-workarounds-part-2.aspx</link><pubDate>Thu, 20 Sep 2012 03:18:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:1295678</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=1295678</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/09/19/azure-table-storage-limitations-and-solutions-workarounds-part-2.aspx#comments</comments><description>&lt;p&gt;This is part two of 2 parts posts discussing the limitations in Azure table storage. It’s highly recommended to read first &lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/08/13/azure-table-storage-limitations-and-solutions-workarounds-part-1.aspx" target="_blank"&gt;Part 1&lt;/a&gt;. In this part I will discuss the querying limitations. Using table storage as your persistence layer – you need to be able to query the storage efficiently. The .NET layer above Table Storage (CloudTableClient) exposes the CreateQuery method that returns DataServiceQuery that implements IQueryable&amp;lt;T&amp;gt;&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DataServiceQuery&amp;lt;T&amp;gt; CreateQuery&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; entitySetName);&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;meaning you can write whatever LINQ query you want and it will compile – but only a very small subset is supported as described here – &lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/dd135725.aspx" target="_blank"&gt;Query Operators (Table Service Support)&lt;/a&gt;. The only supported query operators (it’s easier than writing what is not supported) are: From,Where,Take,First,FirstOrDefault and select.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Limitation #1 – query returns a large number of rows (more than 1000)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Querying table storage using the API above will return a maximum of 1000 entities – this is a good practice and in this case the table storage RESTful service will return a response that contains a continues token to retrieve the next data – to be precise if the query takes more than 5 second or we cross to other partition the query will return. But what if we need to get more then 1000 entities? In this case we have two options:&lt;/p&gt;
&lt;p&gt;&lt;u&gt;Using Paging&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;As I mentioned before if not all data returns a continues token is returned as part of the response – query using this token will return the next result set part of the complete result – this can be implemented using an object called CloudTableQuery&amp;lt;T&amp;gt; – read the details in this excellent &lt;a href="http://blogs.msdn.com/b/jimoneil/archive/2010/10/05/azure-home-part-7-asynchronous-table-storage-pagination.aspx" target="_blank"&gt;post&lt;/a&gt; by Jim O`Neil&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;u&gt;Query As TableServiceQuery&lt;/u&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The simpler case is when we don’t really need paging we just need all the results (and we know that it won’t be a lot more than 1000) – the same CloudTableQuery&amp;lt;T&amp;gt; implements IQueryable&amp;lt;T&amp;gt; but query using it will do the paging under the hood returning all the data needed – more then 1000 rows. simply instead of writing:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;context.Blogs.ToList();&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;Modify it to:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;context.Blogs.AsTableServiceQuery().ToList();&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;and it will query the service as much as needed (using the continues token) – but beware this can be very slow if you have a lot of data so use it wisely.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Limitation #2 – order by&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;As I mentioned in the beginning of the post most of the LINQ operators are not supported – like order by. So what can we do ? Well if we want the data to retrieve by &lt;b&gt;one specific order – for all queries&lt;/b&gt; we can use the fact that the data is stored and retrieved in lexicographic order meaning&amp;nbsp; query the data in a partition will return by their lexicographic order in the partition and the partitions will be returned by the partition key lexicographic order. Let’s look at real life example (that can come in handy) – we want our entities to be ordered from the most recent creation date to the least recent. here is how it can be done:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;sealed&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; StoredEntity : TableServiceEntity
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;{      
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; StoredEntity (DateTime creationDate)
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;     {            
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        RowKey = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color:#8b0000;"&gt;{0:D19}&lt;/span&gt;&amp;quot;,DateTime.MaxValue.Ticks -
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;                 creationDate.ToUniversalTime().Ticks);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        PartitionKey = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color:#8b0000;"&gt;{0:D19}&lt;/span&gt;&amp;quot;,DateTime.MaxValue.Ticks -
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;                 creationDate.Date.ToUniversalTime().Ticks);     
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;     } 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;Explanation of the above: format D19 meaning decimal number with 19 digits (turns 1 to 0000…..0000000001) which is in inverse proportion to the max date.We set the partition key to be a 19 digits string by the date (&lt;b&gt;without time&lt;/b&gt;) and the row key inside is 19 digits string by the data include the time. we divided the data to partition keys by dates and inside the partition the data is ordered by the full date and time.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Limitation #3 – query like operator&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;String operators can be very useful especially when we need to implement a free text search functionality on our data. In this case we don’t have a real solution beside using additional storage that has free text capabilities like &lt;a href="http://lucene.apache.org/core/" target="_blank"&gt;lucene&lt;/a&gt;&amp;nbsp; and query it. The only string operator that is supported is &lt;b&gt;CompareTo. &lt;/b&gt;So we cannot turn compartTo to like but we can implement “starts with” functionality. Lets say we want to ask if the property “Col” starts with the string “yes” we find the following lexicographic string which is “ye&lt;font style="background-color:#ffff00;"&gt;t&lt;/font&gt;” (T comes after S) and query if:&lt;/p&gt;
&lt;div id="codeSnippetWrapper" class="csharpcode-wrapper"&gt;
&lt;div id="codeSnippet" class="csharpcode"&gt;&lt;pre class="alt"&gt;c.Col.CompareTo(&lt;span class="str"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;) &amp;gt;= 0 &amp;amp;&amp;amp; c.Col.CompareTo(&lt;span class="str"&gt;&amp;quot;yet&amp;quot;&lt;/span&gt;) &amp;lt; 0&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;and you have &amp;lt;==&amp;gt; &lt;/p&gt;
&lt;div id="codeSnippetWrapper" class="csharpcode-wrapper"&gt;
&lt;div id="codeSnippet" class="csharpcode"&gt;&lt;pre class="alt"&gt;c.Col.StartsWith(&lt;span class="str"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;It’s not like but just maybe it can match your needs. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Summery&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Azure table storage is not bad (it’s actually amazing &lt;img src="http://blogs.microsoft.co.il/blogs/oshvartz/wlEmoticon-thumbsup_4AAA43D7.png" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" class="wlEmoticon wlEmoticon-thumbsup" alt="Thumbs up" /&gt;) giving unlimited scalable storage of strong typed entities. I’m just saying that using Azure table storage as your &lt;b&gt;only&lt;/b&gt; persistence layer can be problematic if your requirements cannot be answered because of the limitations above and in the previous post. So check carefully your needs not only for the first phase but for the full implementation and future planing because changing from one storage infrastructure to the other can be very painful – I don’t believe that abstraction will work in this case because sooner or later you start using specific table storage features and change it may be too expensive.&lt;/p&gt;
&lt;p&gt;Cheers,Offir&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=1295678" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Azure/default.aspx">Azure</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Azure+Table+Storage/default.aspx">Azure Table Storage</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Cloud/default.aspx">Cloud</category></item><item><title>Azure Table Storage – limitations and solutions/workarounds(Part 1)</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/08/13/azure-table-storage-limitations-and-solutions-workarounds-part-1.aspx</link><pubDate>Tue, 14 Aug 2012 03:12:12 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:1212209</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=1212209</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/08/13/azure-table-storage-limitations-and-solutions-workarounds-part-1.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;Azure table storage – &lt;/strong&gt;is the NoSQL storage key/value based part of Microsoft Azure cloud services. If you are not familiar with Azure table storage I recommend you to first read &lt;a href="https://www.windowsazure.com/en-us/develop/net/how-to-guides/table-services/" target="_blank"&gt;here&lt;/a&gt;. Recently I was working on a very simple application that is hosted on the cloud (simple web role). My previous experience with NoSQL was mostly using &lt;a href="http://ravendb.net/" target="_blank"&gt;RavenDB&lt;/a&gt; (which I really love…) but in this application it was the natural decision to use the out of the box cloud NoSQL storage. Getting started was really easy thanks to the great documentation we have online but when I started to implement the business logic I encountered the limitations and searched for solutions/workarounds – in the next post I want to share with you the limitations I encountered and how to solve them.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Limitation type #1 – Storing your domain object types&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;My application low level architecture is domain driven meaning I have classes/entites that represent my domain – but I cannot store any of them in the table storage due to the following limitations: &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Derive from TableServiceEntity&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;Stored entity must derive from TableServiceEntity&amp;#160; or to be more specific you cannot store any object in azure table storage unless it has the properties: RowKey, PartitionKey and TimeStamp. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Disallow charters in the keys property&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;let’s say you want to store a URL in the PratitionKey – well you can’t because these are the chars you cannot use:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The forward slash (/) character &lt;/li&gt;    &lt;li&gt;The backslash (\) character &lt;/li&gt;    &lt;li&gt;The number sign (#) character &lt;/li&gt;    &lt;li&gt;The question mark (?) character &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Supported property types&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Let’s say you want to store property of complex type (like Address) well you can’t because the supported types are limited to the following list:&amp;#160; &lt;/p&gt;  &lt;table cellspacing="0" cellpadding="0"&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;WCF Data Services type &lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Common Language Runtime type &lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;Details &lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Edm.Binary&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;byte[]&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;An array of bytes up to 64 KB in size.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Edm.Boolean&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;bool&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;A Boolean value.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Edm.DateTime&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;DateTime&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;A 64-bit value expressed as Coordinated Universal Time (UTC). The supported &lt;b&gt;DateTime&lt;/b&gt; range begins from 12:00 midnight, January 1, 1601 A.D. (C.E.), UTC. The range ends at December 31, 9999.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Edm.Double&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;double&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;A 64-bit floating point value.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Edm.Guid&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Guid&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;A 128-bit globally unique identifier.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Edm.Int32&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Int32&lt;/b&gt; or &lt;b&gt;int&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;A 32-bit integer.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Edm.Int64&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Int64&lt;/b&gt; or &lt;b&gt;long&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;A 64-bit integer.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;Edm.String&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;&lt;b&gt;String&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;A UTF-16-encoded value. String values may be up to 64 KB in size.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;Sizes limitations&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Stored entities can have up to 255 properties – and combined size &amp;lt;= 1M and RowKey size must be &amp;lt;= 1KB&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;So at this point you may ask what’s new, we could read about it in MSDN (and you’re right), but now I want to discuss the possible solutions/workaround and their pros and cons.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Divide our objects to domain object and stored objects&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;This solution comes from a lot of other persistence issues in other solutions (like OR\M) and kind of takes the edge from NoSQL power that can store an entity – but maybe it’s good practice to have this separation to keep our Domain Model object free from limitations and restrictions (sometimes we need object that is stored on more than one table). The downside here is obvious: maintenance of classes duplication – you can try using mapping frameworks like &lt;a href="http://automapper.codeplex.com/" target="_blank"&gt;automapper&lt;/a&gt; but the mapping may be complicated and I think you’ll end up writing your own mapping .&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Hooking into DataServiceContext Reading and Writing events&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;This is needed to complete the solution above to help us dealing with Illegal characters by replacing them before writing and after reading. It can be a place holder for dealing with complex types (if they are private they won’t be stored) we can serialize them to a primitive property – as for me I was using JSON.NET to serialize complex type and I’m able to read it when exploring the stored entities (better than using binary serialization then you cannot understand the stored serialized object). The downside here is that you have to create another layer above the DataServiceContext and add your own logic there – not ideal but get’s the job done.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Use “Fat Entities”&lt;/u&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;There are some other alternative, one of them is an open source library to store Strong type entities – under the hood the entity is kept serialized in one property of the TableStorageEntity. &lt;/p&gt;  &lt;p&gt;Here is the entity class: &lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CloudEntity &amp;lt;T&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; RowKey { get; set; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; PartitionKey { get; set; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DateTime Timestamp { get; set; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; T Value { get; set; }    &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;} &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;It’s nice and enables working with one set of entity classes but the downsides are major here: first you cannot query on the entity fields (you can query only on the partition and table keys you set) and second you have to use specific layer that is not exposing all possibilities of the DataServiceContext (downside if you need to use something that is not exposed). This sollution is good if you need simple storing and retrieving by the keys values. get it from &lt;a title="http://code.google.com/p/lokad-cloud/wiki/FatEntities" href="http://code.google.com/p/lokad-cloud/wiki/FatEntities"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Use &lt;/u&gt;&lt;a href="http://www.lucifure.com/"&gt;Lucifure&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another interesting library developed in F# and gives a lot of awesome capabilities – I didn’t try it my self but in general: by using custom attributes on your you can store any entity without any limitations (It’s not an open source so I can’t see the code but I guess it’s done using the dynamic capabilities of F# and creates the rest URL calling the azure table storage service on it’s own). It also gives solutions to other limitations like the size limitations. I will try it and update but it’s really worth looking into. &lt;/p&gt;

&lt;p&gt;here is entity example:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;[StashEntity(Mode=StashMode.Explicit)]&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Employee&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;          &lt;span style="color:#008000;"&gt;// Give the partition, row key and timestamp more meaningful names&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;          [StashPartitionKey]&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;          &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Department;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;          [StashRowKey]&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;          &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; EmployeeId;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;          [StashTimestamp]&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;          DateTime AzureInternal;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Summery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well I’m sure that by now you get the point and I’m sure there are more limitations I missed. Don’t get me wrong Azure Table Storage is great – it gives you out of the box high availability, enable scale and high performance but if your requirement needs a feature that is not supported then you better check the solutions and alternatives before you choose azure table storage and make sure it satisfied your needs.&lt;/p&gt;

&lt;p&gt;In the next post I will talk about the querying limitation and what can we do to overcome them.&lt;/p&gt;

&lt;p&gt;Cheers,Offir&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=1212209" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Azure/default.aspx">Azure</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/NoSQL/default.aspx">NoSQL</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Azure+Table+Storage/default.aspx">Azure Table Storage</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Cloud/default.aspx">Cloud</category></item><item><title>TPL Data Flow Debugger Visualizer</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/06/05/tpl-data-flow-debugger-visualizer.aspx</link><pubDate>Tue, 05 Jun 2012 14:06:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:1112442</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=1112442</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/06/05/tpl-data-flow-debugger-visualizer.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/debug_75A2855F.jpg"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="debug" border="0" alt="debug" src="http://blogs.microsoft.co.il/blogs/oshvartz/debug_thumb_0F2A128D.jpg" width="528" height="61" /&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/tplDataFlow_663EFD83.jpg"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="tplDataFlow" border="0" alt="tplDataFlow" src="http://blogs.microsoft.co.il/blogs/oshvartz/tplDataFlow_thumb_1B880FE9.jpg" width="523" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;TPL Data Flow&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I first encounter &lt;a href="http://msdn.microsoft.com/en-us/library/hh228603%28v=vs.110%29.aspx" target="_blank"&gt;TPL data flow&lt;/a&gt; (part of .NET 4.5 - TPL DTF) during the build conference (I attended &lt;img class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.microsoft.co.il/blogs/oshvartz/wlEmoticon-smile_5215BB2D.png" /&gt; last year) but I must say I didn’t get it then. It sounded too much like RX which I was familiar with. Recently during one of my projects that required high performance CPU bounded – high throughput and low latency my colleague &lt;a href="http://blogs.microsoft.co.il/blogs/alon/" target="_blank"&gt;Alon&lt;/a&gt; the gave the idea – why not using TPL data flow and from then my world changed forever. It’s amazing to how many systems this technology can be suitable to,and for the project I was working on it was perfect. For those of you that are not yet familiar with this technology I suggest reading the article from &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=14782" target="_blank"&gt;here&lt;/a&gt; and see this amazing example of kinect and TPL DTF &lt;font&gt;here&lt;/font&gt; – you’ll thank me later.&lt;/p&gt;  &lt;p&gt;So I created some crazy TPL data flow networks on runtime (~100k different networks) and it worked getting 100% CPU most of the time, leveraging all the cores and getting really good performance – but it was really hard to debug and to understand the flow from the code. It was Alon again that suggested to write debug visualizer – so I did. This is my insights from the process.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Writing Debugger Visualizer&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I don’t know how many of you had the chance to implement debugger visualizer but it is really straightforward if you need only view on a simple object just follow 5-6 steps:&lt;a href="http://msdn.microsoft.com/en-us/library/e2zc529c" target="_blank"&gt;read here&lt;/a&gt;. Finally put your assembly in the visualizer folder (e.g. for VS 11 C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers) and you’re done. This is very simple if your debugging target is simple and serializable. I from the other hand had few issues. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Issues I encountered during the implementation&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Debugger Visualizer Target cannot be interface&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This really surprised me because I know the target I wanted was IDataFlow which is the common interface of TPL data flow which all the blocks need to implement and I discovered that it’s impossible,the target must be a type (can be common base class but not an interface). My solution to this issue was not perfect – I added multiple attributes with all the build in blocks as target.&amp;nbsp; It’s not that bad because the build in blocks are a good start and as long as you start from build in block (what you normally do) then it will discover the rest of the linked block even if they are not part of the build in blocks. In addition it’s not recommended to implement IDataFlow block on your own – there is a lot to take care of: locking synchronization,buffering and more. If one of you Microsoft guys are listening I think adding support of Interface as target of debug visualizer can be very handy.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;DataFlow blocks are not serializable&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As I wrote in the previous paragraph writing&amp;nbsp; debugger visualizer is simple (in most cases…). Well somehow the running process (debugee) needs to transfer the debugged object to the IDE (debugger) this is done by serialization. the thing is non of the IDataFlow block are&amp;nbsp; serialzable. In order to resolve it I implemented derive to VisualizerObjectSource – overriding the GetData method that gets the object and output stream and write it to the stream, the debugger can read the stream from his own size. So I created a serializable object that holds the debug info needed and serialized it to the stream and deserialized on the debugger side. I worked O.K until I tested more complicated networks containing shared blocks meaning two blocks or more are connected to the same block. when serializing I got different reference on the debugger side the solution for this problem was DataContrat attribute:&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;[DataContract(&lt;font&gt;IsReference=true&lt;/font&gt;)] and we get the same reference.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Retrieving the information from the IDataFlow block&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This experience made me learn a lot about the internal implementation of the build in blocks. If you look on this blocks you get a lot of data like Linked blocks Input Queue ext. This data is not part of the block properties – apparently each block has private inner class call Debug view that holds this data. This made me use some hard core reflection (made me understand how powerful reflection is). One more thing was the internal implementation of Joins and links. when you link to Join block it is linked to internal block called JoinBlockTarget&amp;lt;,&amp;gt; which has no data about the linked targets but has reference to the owner Join block .Another example is adding a link with a filter is adding another block called FilterLinkPropagator (see pic above)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;So Start using it now…&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Go to &lt;a href="http://dataflowdebuggerview.codeplex.com/" target="_blank"&gt;http://dataflowdebuggerview.codeplex.com/&lt;/a&gt; download the source/binaries and start using it. I’ll be happy to get your comments and suggestions.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;VS 2012 RC Update:TPL dataflow was moved to NuGet&lt;/strong&gt; (&lt;a href="http://nuget.org/packages/Microsoft.Tpl.Dataflow/4.5.1-rc" target="_blank"&gt;http://nuget.org/packages/Microsoft.Tpl.Dataflow/4.5.1-rc&lt;/a&gt;), pay attention you have to add reference to System.Threadin.Tasks.dll (under the C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5)&lt;/p&gt;  &lt;p&gt;Cheers Offir.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=1112442" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/TPL/default.aspx">TPL</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/VS+2012/default.aspx">VS 2012</category></item><item><title>WCF 4.5 Configuration from external source</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/04/01/wcf-4-5-configuration-from-external-source.aspx</link><pubDate>Sun, 01 Apr 2012 18:48:38 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:1051325</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=1051325</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2012/04/01/wcf-4-5-configuration-from-external-source.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;font size="2"&gt;WCF 4.5&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;There is a lot new in WCF 4.5 you can get the full list &lt;a href="http://msdn.microsoft.com/en-us/library/dd456789(v=vs.110).aspx" target="_blank"&gt;Here&lt;/a&gt;. It always amaze me how much is added from version to version – and the additions are important (UDP, Web Socket binding ext.)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;One specific feature caught my eye – &lt;a href="http://msdn.microsoft.com/en-us/library/hh205277(v=vs.110).aspx" target="_blank"&gt;Configuring WCF Services in Code&lt;/a&gt;. It adds the possibility to setup WCF parameters after it was deployed or when you don’t have access to SerivceHost object.&lt;/p&gt;  &lt;p&gt;This is done by a simple static function you can add to your service implementation:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Configure(ServiceConfiguration config)&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;font size="2"&gt;ServiceConfiguration allowing to add endpoints, behaviors ext. This is nice but why is it so interesting… let’s see the following problem and solution. &lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="2"&gt;Problem - WCF Configuration in enterprise application&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;I think almost every one that developed enterprise application with WCF service as the server side entry point felt this pain. You want to be able to manage your WCF services configurations from single place – if you have more then one service defined you don’t want to use files for configuration and you want to persist the WCF configuration in one place. sure you can configure WCF in code (if you have access to ServiceHost) but you cannot use the same system.serviceModel configuration section – load it from external source. &lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="2"&gt;Solutions – before WCF 4.5&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;I seen a lot of solutions along the way:&lt;/font&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;font size="2"&gt;Implementing your own structure for WCF configuration and write a code that apply it on the service host object – the major downside here is that you have to duplicate the code that exists somewhere inside WCF that reads system.serviceModel configuration and build the matching WCF objects: Bindings, Behaviors ext. &lt;/font&gt;&lt;/li&gt;

  &lt;li&gt;&lt;font size="2"&gt;I saw complicated solution that use reflection of the ServiceHost object and inject the system.serviceModel configuration section – the downside here is the risk (you can fail on runtime and the internal may change)&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="2"&gt;Nice solution by Alon Fliess was to create another app domain and associate specific file to the new domain allowing to read configuration from external file – read about it &lt;a href="http://blogs.microsoft.co.il/blogs/alon/archive/2008/03/12/hosting-plug-in-wcf-services.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/font&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;font size="2"&gt;All the solution above has some downside and this is because ServiceHost was not build to get the configuration from external source – all the solution above are workarounds.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="2"&gt;Solve it WCF 4.5 style&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;This solution is not perfect too (read limitation) but it uses given WCF API which means it is the best we currently have. So as I mention the static function Configure was added but what is doing the trick it the function LoadFromConfiguration of the ServiceConfiguration object. This allows us to write this code:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; EchoService : IEchoService&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Configure(ServiceConfiguration config)&lt;br /&gt;       {&lt;br /&gt;           var cfg = MyConfigurationManager.GetConfigurationByServiceType(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(EchoService));&lt;br /&gt;           config.LoadFromConfiguration(cfg);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Echo(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; input)&lt;br /&gt;       {&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;Echo:{0}&amp;quot;&lt;/span&gt;, input);&lt;br /&gt;       }&lt;br /&gt;   }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;font size="2"&gt;All the magic is done in the “MyConfigurationManager” which can have is own logic – reading from DB by given parameters (could be service type, machine name ext.) and returns System.Configuration object that is loaded using the LoadFromConfiguration.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;to complete my example my configuration manager read it from a file:&lt;/font&gt; &lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;strong&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; MyConfigurationManager&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; Configuration GetConfigurationByServiceType(Type serviceType)&lt;br /&gt;       {&lt;br /&gt;           var fileMap = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ExeConfigurationFileMap() { ExeConfigFilename = Path.Combine(Environment.CurrentDirectory, &lt;span style="color:#006080;"&gt;&amp;quot;ExternalConfiguration.xml&amp;quot;&lt;/span&gt;) };&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);&lt;br /&gt;&lt;br /&gt;       }&lt;br /&gt;   }&lt;/strong&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Limitation:&lt;/strong&gt;Note that LoadFromConfiguration ignores &amp;lt;&lt;strong&gt;host&lt;/strong&gt;&amp;gt; settings within the &amp;lt;&lt;strong&gt;service&lt;/strong&gt;&amp;gt; tag of &amp;lt;&lt;strong&gt;system.serviceModel&lt;/strong&gt;&amp;gt;. Conceptually, &amp;lt;&lt;strong&gt;host&lt;/strong&gt;&amp;gt; is about host configuration, not service configuration, and it gets loaded before the Configure method executes. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I would like to be able to pass to ServiceHost Configuration object. we are still not there…maybe at WCF 5.0 &lt;img style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.microsoft.co.il/blogs/oshvartz/wlEmoticon-smile_2C3C75FA.png" /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160; Cheers, Offir&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=1051325" width="1" height="1"&gt;</description></item><item><title>Windows Build- my first impressions</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/09/15/windows-build-my-first-impressions.aspx</link><pubDate>Thu, 15 Sep 2011 12:15:19 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:901014</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=901014</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/09/15/windows-build-my-first-impressions.aspx#comments</comments><description>&lt;p&gt;Well I’m here at Anaheim enjoying every second (I’m a geek what can I say). Wanted to share some of my thoughts. I’ll just note that these word are written using new cool Win 8 Samsung tablet.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/IMG_6245_2129F500.jpg"&gt;&lt;img title="IMG_6245" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="IMG_6245" src="http://blogs.microsoft.co.il/blogs/oshvartz/IMG_6245_thumb_524E5102.jpg" width="644" height="431" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;So I heard a lot of keywords and pieces of information in the passed days here are some:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Immersive &lt;/li&gt;    &lt;li&gt;Fast and Fluid &lt;/li&gt;    &lt;li&gt;Modern &lt;/li&gt;    &lt;li&gt;Metro style &lt;/li&gt;    &lt;li&gt;WinRT&lt;/li&gt;    &lt;li&gt;HTML5/JS&lt;/li&gt;    &lt;li&gt;Application Contracts&lt;/li&gt;    &lt;li&gt;…&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I’m still digesting all the information but there is one issue that really amazed me because it can really cause revolution in application capabilities. Windows 8 really bring new perspective on how applications should behave and interact. &lt;/p&gt;  &lt;p&gt;I’m talking about the keyword &amp;quot;&lt;strong&gt;Application Contracts” &lt;/strong&gt;(e.g. sharing contract, picker contract, Search contract…)&lt;strong&gt; , &lt;/strong&gt;when looking on it from the software architecture perspective: the infrastructure is the OS (windows) and application may considered as modules all part of a one large application. Everybody knows that a good design is keeping the modules decoupled but enable interaction between them using plugin/IoC infrastructure – like MEF. Microsoft is bringing the same notion to the Metro Application using Win 8 (the infrastructure) enabling plugin infrastructure – Application Contracts. This way application may expose itself in decoupled way and consume other applications services without even know about each other. So Microsoft is introducing new application plugin infrastructure – thinking about it this can really give us new generation of application that speaks with one another and enhance each other – the example I can think of is GPS locator application that expose his search capabilities consumed by social network application allows the user to know what are his friends location.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/IMG_6248_2AAA6589.jpg"&gt;&lt;img title="IMG_6248" style="display:inline;" alt="IMG_6248" src="http://blogs.microsoft.co.il/blogs/oshvartz/IMG_6248_thumb_0B89D95A.jpg" width="640" height="427" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Re-imagine this…&lt;/p&gt;  &lt;p&gt;Cheers Offir&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=901014" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category></item><item><title>WCF Performance Using Datasets – Part 2</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/07/23/wcf-performance-using-datasets-part-2.aspx</link><pubDate>Sat, 23 Jul 2011 19:44:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:876004</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=876004</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/07/23/wcf-performance-using-datasets-part-2.aspx#comments</comments><description>&lt;p&gt;start with reading &lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/07/03/wcf-performance-using-datasets-part-1.aspx"&gt;WCF Performance Using Datasets – Part 1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Can it be ?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I asked this question over and over – because WCF is clearly faster (see Eyal Vardi comment in part 1). I tried several Binding options including some custom binding , I asked some people to look at my code and up to now no one has manage to contradict my benchmark. I invite each one of you to try (write you own tester) my contract is simple:&lt;/p&gt;
&lt;div style="BORDER-BOTTOM:silver 1px solid;TEXT-ALIGN:left;BORDER-LEFT:silver 1px solid;PADDING-BOTTOM:4px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:#f4f4f4;MARGIN:20px 0px 10px;PADDING-LEFT:4px;WIDTH:97.5%;PADDING-RIGHT:4px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;MAX-HEIGHT:200px;FONT-SIZE:8pt;OVERFLOW:auto;BORDER-TOP:silver 1px solid;CURSOR:text;BORDER-RIGHT:silver 1px solid;PADDING-TOP:4px;" id="codeSnippetWrapper"&gt;
&lt;div style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:#f4f4f4;BORDER-LEFT-STYLE:none;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;BORDER-RIGHT-STYLE:none;FONT-SIZE:8pt;OVERFLOW:visible;PADDING-TOP:0px;" id="codeSnippet"&gt;&lt;pre style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:white;MARGIN:0em;BORDER-LEFT-STYLE:none;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;BORDER-RIGHT-STYLE:none;FONT-SIZE:8pt;OVERFLOW:visible;PADDING-TOP:0px;"&gt;[ServiceContract]&lt;/pre&gt;&lt;pre style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;BORDER-LEFT-STYLE:none;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;BORDER-RIGHT-STYLE:none;FONT-SIZE:8pt;OVERFLOW:visible;PADDING-TOP:0px;"&gt; &lt;span style="COLOR:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="COLOR:#0000ff;"&gt;interface&lt;/span&gt; IPerfService&lt;/pre&gt;&lt;pre style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:white;MARGIN:0em;BORDER-LEFT-STYLE:none;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;BORDER-RIGHT-STYLE:none;FONT-SIZE:8pt;OVERFLOW:visible;PADDING-TOP:0px;"&gt;  {&lt;/pre&gt;&lt;pre style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;BORDER-LEFT-STYLE:none;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;BORDER-RIGHT-STYLE:none;FONT-SIZE:8pt;OVERFLOW:visible;PADDING-TOP:0px;"&gt;       [OperationContract]&lt;/pre&gt;&lt;pre style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:white;MARGIN:0em;BORDER-LEFT-STYLE:none;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;BORDER-RIGHT-STYLE:none;FONT-SIZE:8pt;OVERFLOW:visible;PADDING-TOP:0px;"&gt;       DataSet LoadDataSet(DataSet ds);&lt;/pre&gt;&lt;pre style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;BORDER-LEFT-STYLE:none;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;BORDER-RIGHT-STYLE:none;FONT-SIZE:8pt;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BACKGROUND-COLOR:white;MARGIN:0em;BORDER-LEFT-STYLE:none;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;BORDER-RIGHT-STYLE:none;FONT-SIZE:8pt;OVERFLOW:visible;PADDING-TOP:0px;"&gt;  }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;b&gt;Why is WCF slower for Datasets ?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I decided to use a profiler and look at the time consuming deviation. I like using Dot Trace profiler because&amp;nbsp;it is very simple and clear. I was sampling one of 1000 iteration after 100 iteration.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Hold tight we are going deep&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;You can see that the WCF call (ClientLoadDataSetSelfHost) took 719 ms and the Web Service call (LoadDataSet) took 619 ms &lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/per1_4F35029A.png"&gt;&lt;img style="BACKGROUND-IMAGE:none;BORDER-BOTTOM:0px;BORDER-LEFT:0px;PADDING-LEFT:0px;PADDING-RIGHT:0px;DISPLAY:inline;BORDER-TOP:0px;BORDER-RIGHT:0px;PADDING-TOP:0px;" title="per1" border="0" alt="per1" src="http://blogs.microsoft.co.il/blogs/oshvartz/per1_thumb_68505CD2.png" width="572" height="198" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Drilling down I discovered that this gap was a result in the gap of desterilize method duration – makes sense because this is most of the work (DataSet of 15,000 rows).&lt;/p&gt;
&lt;p&gt;&lt;i&gt;it&amp;#39;s Important&amp;nbsp;to remember that when serializing / deserializing an object that is implementing IXmlSerializable it doesn&amp;#39;t meter what kind of serializer is defined it will use the object IXmlSerializable&amp;nbsp; implementation – this can be very problematic when using hybrid option when object that not implementing IXmlSerializable&amp;nbsp; holds members that implements IXmlSerializable but discussing this can write full other post. &lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Both are using: System.Data.DataSet.ReadXml(XmlReader)&amp;nbsp;&amp;nbsp; (from System.Xml.Serialization.IXmlSerializable)&amp;nbsp; - in this function we see the 100 ms diff in duration between Web Service and WCF.&lt;/p&gt;
&lt;p&gt;Digging deeper going to the method: System.Data.XmlDataLoader.LoadTable(DataTable, Boolean) called from System.Data.XmlDataLoader.LoadData(XmlReader) called from System.Data.DataSet.ReadXmlDiffgram(XmlReader).&lt;/p&gt;
&lt;p&gt;In WCF:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/WCFPerf_6D22EAC1.png"&gt;&lt;img style="BACKGROUND-IMAGE:none;BORDER-BOTTOM:0px;BORDER-LEFT:0px;PADDING-LEFT:0px;PADDING-RIGHT:0px;DISPLAY:inline;BORDER-TOP:0px;BORDER-RIGHT:0px;PADDING-TOP:0px;" title="WCFPerf" border="0" alt="WCFPerf" src="http://blogs.microsoft.co.il/blogs/oshvartz/WCFPerf_thumb_174272DD.png" width="640" height="274" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Web Service:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/perfWebService_4A5E60AC.png"&gt;&lt;img style="BACKGROUND-IMAGE:none;BORDER-BOTTOM:0px;BORDER-LEFT:0px;PADDING-LEFT:0px;PADDING-RIGHT:0px;DISPLAY:inline;BORDER-TOP:0px;BORDER-RIGHT:0px;PADDING-TOP:0px;" title="perfWebService" border="0" alt="perfWebService" src="http://blogs.microsoft.co.il/blogs/oshvartz/perfWebService_thumb_66ABA2CC.png" width="655" height="278" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;you can see that most of the method takes more time and this is due to the XMLReader specific type that DataSet is choosing in runtime:&lt;font color="#ff0000"&gt; in web service XMLTextReader in WCF XMLBinaryReader&lt;/font&gt; – reading using BinaryXMLReader is taking more time.&lt;/p&gt;
&lt;p&gt;When I used text encoding still in WCF it was using XMLBufferReader and not XMLTextReader. In addition I tried most of the binding options but still DataSet is choosing the XMLBufferReader – I’m open for your suggestions. If we could define specific binding that will get DataSet to behave the same as in WebService it could be very useful. The thing is we cannot modify DataSet Code – the XMLReader specific type choosing part. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;What is the solution&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I’ll start with what is not the solution for sure which is going back to Web Services – we cannot allow our application not moving to WCF because we need WCF power:Security, full separation of binding from service implementation , easy maintaining , tracing ,error handling and most important this is the technology Microsoft is developing and supporting NOW.&lt;/p&gt;
&lt;p&gt;I’ll divide my solution to two main options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The most correct but annoying solutions: Do not use data set – it’s a large cumbersome out dated object. In addition it’s not strong typed meaning it can cause to fail on runtime. Now the way to go is Domain driven. &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;I know the fist option is not always possible – sometimes too costly and too risky still this is the way to go.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DataSet Surrogate – I saw it in several places over the web (&lt;a href="http://support.microsoft.com/kb/829740"&gt;here is one&lt;/a&gt;). This solution is to hold the all&lt;b&gt; dataset data&lt;/b&gt; in other fast serialized object and past the surrogate object over the wire. You can change the WCF method signature to pass this SurrageDataSet or better use Parameter Inspectors (&lt;a href="http://cgeers.com/2008/11/09/wcf-extensibility-parameter-inspectors/"&gt;read more here&lt;/a&gt;) to do it using WCF extensibility options.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;You may encounter the situation of passing DataSets in WCF only on legacy solutions but it’s important that when refactoring old application, you should be aware that moving to WCF not necessary means memory improvement – mainly if all your object model is data sets (very common in legacy solutions).&lt;/p&gt;
&lt;p&gt;I implemented and tested my own DataSet surrogate (not supporting relations) and in my bench mark WCF was faster then Web Service in ~15%. I’m sure it depends on number of tables and rows and to rebuild DataSet takes time too. Still I think this can bring significant performance improvement. &lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=876004" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Web+Service/default.aspx">Web Service</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/WCF/default.aspx">WCF</category></item><item><title>WCF Performance Using Datasets – Part 1</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/07/03/wcf-performance-using-datasets-part-1.aspx</link><pubDate>Mon, 04 Jul 2011 02:51:24 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:849137</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=849137</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/07/03/wcf-performance-using-datasets-part-1.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;It’s all started when I encountered a strange behavior in one of the systems I work on.&lt;/p&gt;  &lt;p&gt;The system is a legacy system that uses a simple client server architecture implementing using web service – this was pre-WCF time so the options were only .NET remoting and web services. Now as part of major refactoring process of the system we decided to replace the communication layer from WS to WCF.&lt;/p&gt;  &lt;p&gt;The motivation is obvious:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Alignment with Microsoft latest infrastructure. &lt;/li&gt;    &lt;li&gt;performance improvement – http to TCP/ Binary encoding. &lt;/li&gt;    &lt;li&gt;Easy maintenance. &lt;/li&gt;    &lt;li&gt;Easy monitoring and configuration. &lt;/li&gt;    &lt;li&gt;Extendible – interception points (behaviors). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;After the modification was completed I found that the system became slightly &lt;strong&gt;slower&lt;/strong&gt;&amp;#160; – how can it be.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;WCF performance vs. Web Service – What do we know&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This bring me to article from 2007 written by Microsoft: &lt;a href="http://msdn.microsoft.com/en-us/library/bb310550.aspx"&gt;http://msdn.microsoft.com/en-us/library/bb310550.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;“&lt;em&gt;To summarize the results, WCF is 25%—50% faster than ASP.NET Web Services, and approximately 25% faster than .NET Remoting. Comparison with .NET Enterprise Service is load dependant, as in one case WCF is nearly 100% faster but in another scenario it is nearly 25% slower. For WSE 2.0/3.0 implementations, migrating them to WCF will obviously provide the most significant performance gains of almost 4x.”&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;My Benchmark&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Still articles are articles and facts are facts – “the costumer is always right” &lt;img style="border-bottom-style:none;border-right-style:none;border-top-style:none;border-left-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.microsoft.co.il/blogs/oshvartz/wlEmoticon-smile_3F6C4B0E.png" /&gt;&lt;/p&gt;  &lt;p&gt;In addition in the article there was no mention of datasets specifically.&lt;/p&gt;  &lt;p&gt;In the legacy system we mostly use DataSet (I know pretty ugly but this is what we did in a legacy code what can I do…).&lt;/p&gt;  &lt;p&gt;So I decided doing my own simple benchmark.&lt;/p&gt;  &lt;p&gt;I tested two scenarios:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Pass 10000 objects – the object include two fields: integer and string. &lt;/li&gt;    &lt;li&gt;Pass “large” dataset – includes one table the has two string columns contains 10000 rows. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The services types:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Simple ASMX web service. &lt;/li&gt;    &lt;li&gt;Self hosted WCF service. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;the client makes sequential call to the services: 1 then 2 and I measure the duration in milliseconds.&lt;/p&gt;  &lt;p&gt;I repeat the same test 1000 time and use the average duration of the last 100 test runs. &lt;/p&gt;  &lt;p&gt;here are the results (duration in milliseconds):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/image_057D0822.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/oshvartz/image_thumb_2A9A528E.png" width="367" height="269" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/image_2F9C903D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/oshvartz/image_thumb_3FC85836.png" width="368" height="222" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Conducting a Benchmark Notes&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Not doing the following can get you faulty results.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Remember to run the tests not using Visual Studio (not using the .vshost.exe process). &lt;/li&gt;    &lt;li&gt;Run the sources complied in “Release”. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Conclusions&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;My conclusion is for dataset transfer &lt;em&gt;&lt;strong&gt;Web Service is faster than WCF&lt;/strong&gt;&lt;/em&gt; (around ~40% faster). &lt;/p&gt;  &lt;p&gt;So when choosing to upgrade legacy code to use WCF – will not always increase your system performance – if you use mostly datasets your system may become slower. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What’s next&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is only the start because:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;First we need to understand what is the cause for the performance decrease – why is WCF slower only for DataSets. &lt;/li&gt;    &lt;li&gt;Second we need to find a solution to use WCF but still keep our performance or better improve – going back to Web Service is not an option. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So stay tune for part 2, I promise it’s we’ll be worthwhile.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/07/23/wcf-performance-using-datasets-part-2.aspx" target="_blank"&gt;http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/07/23/wcf-performance-using-datasets-part-2.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Cheers&lt;/p&gt;  &lt;p&gt;Offir&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=849137" width="1" height="1"&gt;</description></item><item><title>Publish/Subscriber Using Routing Service (WCF4)</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/02/20/pub-sub-using-routing-service-wcf4.aspx</link><pubDate>Mon, 21 Feb 2011 02:05:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:794334</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>454</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=794334</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/02/20/pub-sub-using-routing-service-wcf4.aspx#comments</comments><description>&lt;p&gt;Hi all.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/files/folders/oshvartz/entry792492.aspx"&gt;Download Code&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Few weeks ago I went to an interesting lecture of&amp;nbsp; &lt;a href="http://blogs.microsoft.co.il/blogs/idof/"&gt;Ido Flatow&lt;/a&gt; called: “What’s new in WCF4”. The lecture was very good mostly because it was the first time somebody gathered and organized the new abilities of WCF 4, and the material level in my opinion was pretty high. One of the features Ido talked about was the Routing Service. That feature just amazed me, I found it very powerful and useful in many scenarios: load balancing, on service failure, content base routing, bridge and more (&lt;a href="http://msdn.microsoft.com/en-us/library/ee517423.aspx"&gt;MSDN Link&lt;/a&gt;). &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Pub/Sub Solutions&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I was at the time examining some pub/sub solutions. Discussing them can easily fill a series of posts. I will only mention few points on the subject: First there are many options available: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://ayende.com/Blog/archive/2008/12/17/rhino-service-bus.aspx"&gt;Rhino Service Bus&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nservicebus.com/"&gt;NService Bus&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://masstransit-project.com/"&gt;MassTransit&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;WCF solution – contract base &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163537.aspx"&gt;Juval Lowy Solution&lt;/a&gt;. &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Second, the Pub/Sub solution I looked for have several significant requirements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The usage must be very simple and clear – strong typed without complicated configuration&amp;nbsp; – something like the Mass Transit interface(this ruled out the last option). &lt;/li&gt;
&lt;li&gt;I didn’t want the MSMQ based solution (the first 3) – one of the reasons is that MSMQ has size limitation (4 Mega) – although there are ways to reduce the size limitation. &lt;/li&gt;
&lt;li&gt;The pub/sub host must be completely loose coupled from publishers and subscribers. &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;I wanted WCF based solution but I had some bad experience using the Duplex capabilities of WCF – it was causing many problems, especially when the publisher server goes down and back up.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;My Pub/Sub POC&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;During Ido’s lecture I realized that Routing service is perfect for Pub/Sub solution. Routing Service Distribute massage to all subscribers – and we get out of the box loose coupled of Binding, Security and contract. Each subscriber is hosting one way WCF service per massage type to get notification, so my first step was to define the client interface (requirement number 1).&lt;/p&gt;
&lt;p&gt;The interface:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;interface&lt;/span&gt; IPubSubClient&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;     &lt;span&gt;void&lt;/span&gt; Publish&amp;lt;T&amp;gt;(T message);&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;     &lt;span&gt;void&lt;/span&gt; Subscribe&amp;lt;T&amp;gt;(&lt;span&gt;ref&lt;/span&gt; Action&amp;lt;T&amp;gt; handler);&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;     &lt;span&gt;void&lt;/span&gt; Unsubscribe&amp;lt;T&amp;gt;(&lt;span&gt;ref&lt;/span&gt; Action&amp;lt;T&amp;gt; handler);&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is how to Configure and run the routing service:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;ServiceHost pubServiceHost = &lt;span&gt;new&lt;/span&gt; ServiceHost(&lt;span&gt;typeof&lt;/span&gt;(RoutingService));&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;ConfigureRouter(pubServiceHost); &lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;pubServiceHost.Open();&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Configure Router:&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var routerContract = &lt;span&gt;typeof&lt;/span&gt;(ISimplexDatagramRouter);&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span&gt;string&lt;/span&gt; routerAddress = &lt;span&gt;&amp;quot;net.tcp://localhost:8888/publisher&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;Binding routerBinding = &lt;span&gt;new&lt;/span&gt; NetTcpBinding();&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span&gt;//add the endpoint the router will use to recieve messages&lt;/span&gt;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;serviceHost.AddServiceEndpoint(routerContract, routerBinding, routerAddress);&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span&gt;//create a new routing configuration object&lt;/span&gt;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;RoutingConfiguration rc = &lt;span&gt;new&lt;/span&gt; RoutingConfiguration();&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;rc.RouteOnHeadersOnly = &lt;span&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;serviceHost.Description.Behaviors.Add(&lt;span&gt;new&lt;/span&gt; RoutingBehavior(rc));&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Writing the POC was quite fluent, which made me more sure that the Routing Service is really suitable in this case.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Interesting Points&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The code lies in front of you, still I wanted to point out some points I think are important:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure the routing service is very simple using the class RoutingConfiguration we can add/remove keys from the filter table – which holds the routing table. &lt;/li&gt;
&lt;li&gt;We can change the Filter table during run time by calling ApplyConfiguration: &lt;/li&gt;&lt;/ul&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span&gt;internal&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Subscribe(&lt;span&gt;string&lt;/span&gt; messageType, &lt;span&gt;string&lt;/span&gt; endpointAddress)&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span&gt;lock&lt;/span&gt; (_routingConfiguration)&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        ContractDescription cd = ContractDescription.GetContract(&lt;span&gt;typeof&lt;/span&gt;(IRequestReplyRouter));&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        ServiceEndpoint servEndpoint = &lt;span&gt;new&lt;/span&gt; ServiceEndpoint(cd, &lt;span&gt;new&lt;/span&gt; NetTcpBinding(), &lt;span&gt;new&lt;/span&gt; EndpointAddress(endpointAddress));&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        _routingConfiguration.FilterTable.Add(&lt;span&gt;new&lt;/span&gt; MessageTypeMessageFilter(messageType),&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                     &lt;span&gt;new&lt;/span&gt; List&amp;lt;ServiceEndpoint&amp;gt;() { servEndpoint });&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        _routingHost.Extensions.Find&amp;lt;RoutingExtension&amp;gt;().ApplyConfiguration(_routingConfiguration);&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;The subscribers open the the notification service channel during runtime , using the same port (although they can use other random port numbers) &lt;i&gt;– in order for it to work you must enable net.tcp&amp;nbsp; port sharing by going the windows services (running services.msc) and start the service “&lt;b&gt;NetTcpPortSharing&lt;/b&gt;”.&lt;/i&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span&gt;private&lt;/span&gt; ServiceHost CreateNewService&amp;lt;T&amp;gt;(List&amp;lt;Action&amp;lt;T&amp;gt;&amp;gt; handlers)&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    ServiceHost pubServiceHost = &lt;span&gt;new&lt;/span&gt; ServiceHost(&lt;span&gt;new&lt;/span&gt; PublisherService&amp;lt;T&amp;gt;() { Handlers = handlers });&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span&gt;string&lt;/span&gt; pubAddress = &lt;span&gt;string&lt;/span&gt;.Format( &lt;span&gt;&amp;quot;net.tcp://{0}:7777/pub/{1}/{2}&amp;quot;&lt;/span&gt;,Environment.MachineName,&lt;span&gt;typeof&lt;/span&gt;(T).Name,Guid.NewGuid());&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    var portSharingBinding = &lt;span&gt;new&lt;/span&gt; NetTcpBinding();&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    portSharingBinding.PortSharingEnabled = &lt;span&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    pubServiceHost.AddServiceEndpoint(&lt;span&gt;new&lt;/span&gt; ServiceEndpoint(ContractDescription.GetContract(&lt;span&gt;typeof&lt;/span&gt;(IPublisherService&amp;lt;T&amp;gt;)), portSharingBinding, &lt;span&gt;new&lt;/span&gt; EndpointAddress(pubAddress)));&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span&gt;return&lt;/span&gt; pubServiceHost;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;I’m using XPathMessageFilter for matching massage type to his subscribers.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I am printing the latency of the message (avg. of ~60 MilliSec in my computer) and I notice that even when running ~50 subscribers the latency remain the same – this lays in the Routing Service implementation that distribute the massages efficiently. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Summery&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Download and run the POC (don’t forget to start the port sharing service) – run the Pub/Sub Server and as much clients as you like. Please share your comments or/and thoughts.&lt;/p&gt;
&lt;p&gt;Cheers Offir.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=794334" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/WCF/default.aspx">WCF</category></item><item><title>EF4 In real life and using Code Only – Yes We Can ?</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2010/06/08/ef4-in-real-life-and-using-code-only-yes-we-can.aspx</link><pubDate>Wed, 09 Jun 2010 02:58:37 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:651621</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=651621</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2010/06/08/ef4-in-real-life-and-using-code-only-yes-we-can.aspx#comments</comments><description>&lt;p&gt;Hi all it&amp;#39;s been a while but i didn&amp;#39;t have anything interesting to write about. Lately I was involved in a process of choosing the technology used in Data access infrastructure of new application, and let&amp;#39;s just say it wasn&amp;#39;t a simple decision but a fascinating one.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;General&lt;/strong&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The decision process was interesting and long, the dilemma was reduced at the end to decide between two ORM solutions: NHibernate and Entity Framework 4 – EF4 (I&amp;#39;ll give some details below). Finally we decided to go with &lt;strong&gt;EF4&lt;/strong&gt;. The risky part in this decision is that EF4 is only lately released (with vs 2010 RTM) and we don&amp;#39;t have any known enterprise application using it in production.I Just want to add into considerations that the application Client is developed at Silverligth 4.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Special requirements – Code Only.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The specific application had one additional special need: defining the DB mapping in runtime which means do not use a static edmx file. The solution was to use the Code Only feature – which is currently part of CTP (&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=af18e652-9ea7-478b-8b41-8424b94e3f58&amp;amp;displaylang=en" target="_blank"&gt;Microsoft ADO.NET Entity Framework Feature CTP 3&lt;/a&gt;) and not part of the release. This issue was added to the danger factor – can we use it to define a complicated model – does it answers our needed scenarios and is it good enough from performance point of view.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;EF4 vs NHibernate&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There is a lot to say in this section but I&amp;#39;ll be brief.&lt;/p&gt;  &lt;p&gt;First NHibernate has many advantages over EF4:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Has more fine tuning abilities – scalability and performance. &lt;/li&gt;    &lt;li&gt;Is very mature – works for years in enterprise applications. &lt;/li&gt;    &lt;li&gt;Has more features. &lt;/li&gt;    &lt;li&gt;More Extendable – Open Source. &lt;/li&gt;    &lt;li&gt;Supports more DB types out of the box. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So why to choose EF4 you ask. Well for my specific needs, EF4 is more suitable from the following reasons:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;EF4 is more suitable for working in N-Tear architecture:      &lt;ul&gt;       &lt;li&gt;It has disconnected out of the box solution - the Self Tracking. &lt;/li&gt;        &lt;li&gt;In order to use NHibernate for N-Tear you may need to use DTO because: working N-Tear with NHibernate is not straightforward especially with silverligth for example the many to one navigation property are defined in POCO as interface and the strong but complex lazy loading capabilities of NHibernate are not suitable for N-Tear when your entity is disconnected from the session. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;EF4 is more easy to &lt;strong&gt;start working with&lt;/strong&gt; – you have the model designer and code generation items – and it all comes out of the box (NHibernate has some similar solutions but they supply only part of the features EF4 gives – comes out of the box in VS 2010) . &lt;/li&gt;    &lt;li&gt;EF4 is Microsoft – we cannot ignore this fact. We develop in a Microsoft environment, the .Net framework is evolving (LINQ, Dynamic ,Generics,Covariance …) it makes sense that Microsoft will evolve EF as well and do it more easily because it&amp;#39;s all develops in the same organization. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;EF4 problematic issues&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;while working with EF4 I encountered some problems, some of them are pretty critical.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Code only&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Using the code only was a must because of my special needs (as described above). Although using CTP I must say the work was quite smooth and very intuitive. The problems I encountered were not related to the code only feature specifically, but to EF4 in general. The downside was the lack of documentation and information in general. the best information source I found was the &lt;a href="http://1code.codeplex.com/"&gt;All-In-One Code Framework&lt;/a&gt; from codeplex and the &lt;a href="http://blogs.msdn.com/b/adonet/" target="_blank"&gt;ADO.NET team blog&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The inheritance TPH (table per hierarchy) issue&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;This issue was very surprising for me, I tried to define TPH inheritance with code only (using the example from &lt;a href="http://1code.codeplex.com/"&gt;All-In-One Code Framework&lt;/a&gt;), then I got strange exception (&amp;quot;InvalidException previous cannot be null&amp;quot;). After a short investigation I discovered that the reason was that the derived classes and the base class weren&amp;#39;t located in the same assembly. I checked it without code only feature (with simple edmx file) and the result was the same – an ugly exception. Please tell me if I am doing something wrong or missed something because if not it&amp;#39;s a bug and a big one – most likely that in enterprise applications there will be a separation between the base classes and derived classes. So I did a workaround (too ugly to mention) for this issue, but I&amp;#39;m open for you suggestions how to deal with this problem. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;The inheritance TPT (table per type) issue&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This is a known issue of Entity Framework (from EF1 and still not resolved in EF4). When you define a very common inheritance strategy: each derive is stored in separated table. EF fully supports this strategy but the queries it produces when querying the model is &amp;quot;&lt;strong&gt;evil&lt;/strong&gt;&amp;quot;. evil meaning very long (in some scenarios it can cause exceeding the query string limit if we have many inheritances) and has very poor performance – union of left joins of all the derived tables. EF also supports Hybrid mapping meaning define TPT and gives a condition for each specific type (called discriminator in NHibernate) but when producing the Query EF still generates these &amp;quot;&lt;strong&gt;evil&lt;/strong&gt;&amp;quot; queries.&lt;/p&gt;  &lt;p&gt;I must say this issue is critical and Microsoft should attend it as soon as possible because currently it&amp;#39;s is one of the biggest obstacles when using EF in enterprise applications.&lt;/p&gt;  &lt;p&gt;The Solution is to avoid working from the base class when querying, meaning add and delete should be done from the base (we don&amp;#39;t really have other options), but &lt;strong&gt;when querying work only from the derived&lt;/strong&gt; use the syntax:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;from user in context.Users&lt;strong&gt;.OfType&amp;lt;SpecificUser&amp;gt;();&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;this will generate an efficient inner join query. &lt;/p&gt;  &lt;p&gt;* If you need to query your model from the base type consider using TPH or even consider not using EF4 because currently there is no good solution for this issue.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summery&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Having said that, what is the answer to the question in the title: yes we can ?&lt;/p&gt;  &lt;p&gt;well the answer is still not clear so I&amp;#39;ll say: at this early point it looks like &lt;strong&gt;yes :-)&lt;/strong&gt;. I&amp;#39;m sure all the problems I mentioned will be eventually solved by Microsoft, but for now it works (with some workarounds).In my DAL infrastructure – abstraction layer above EF4 (using Repository and UnitOfWork pattern) I use EF in two ways:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Using code only context.&lt;/li&gt;    &lt;li&gt;Using edmx file - The usual static model.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I&amp;#39;ll update you as the application will get more mature. That&amp;#39;s all, waiting for your comments and\or suggestions.&lt;/p&gt;  &lt;p&gt;Cheers, Offir.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=651621" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/ORM/default.aspx">ORM</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/EF4/default.aspx">EF4</category></item><item><title>Self tracking “Poco’s” (self tracking data transfer objects)</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2009/12/04/self-tracking-poco-s-self-tracking-data-transfer-objects.aspx</link><pubDate>Fri, 04 Dec 2009 23:21:39 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:458359</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=458359</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2009/12/04/self-tracking-poco-s-self-tracking-data-transfer-objects.aspx#comments</comments><description>&lt;p&gt;Recently I worked on a POC with the guidance of &lt;a href="http://blogs.microsoft.co.il/blogs/berniea/"&gt;Bernie Almosni&lt;/a&gt; – Building a layer above the business entities (stored in a data base) with the use of an ORM (as the data access engine). During the process we encountered the disconnected scenario issue (it’ll describe in details below). The Self tacking DTO component was develop by Bernie and myself as a part of the POC – aimed at addressing&amp;#160; the disconnected scenario. We ended up with a generic framework not bound to specific ORM, that I think can be useful to many.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;POC Requirements&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The business entities are POCOs (Plain old CLR object). &lt;/li&gt;    &lt;li&gt;We use inversion of control (specifically unity) so each of the business entities implement an interface. We work &lt;strong&gt;only&lt;/strong&gt; with the interface in our business logic components. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;ORM Context&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Definition: this term is common for all ORMs that supports using POCOs as persistent entities. It describes the component that manages the entities by tracking the entities modifications. Then persist these specific modifications by sending SQL command to the database. In Entity Framework it is the ObjectContext and in NHibernate it is the Session. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Disconnected Scenario&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;the flow:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Load an entity. &lt;/li&gt;    &lt;li&gt;Send it to the client – N-Tier maybe by WCF. (the client doesn’t hold the ORM context so the entity is in a disconnected state). &lt;/li&gt;    &lt;li&gt;The client modifies the entity. &lt;/li&gt;    &lt;li&gt;The client sends the entity back to the server. &lt;/li&gt;    &lt;li&gt;The server synchronizes the modifications with the database – this is the hard part since the server doesn’t know what modifications where made, if any.&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Self Tracking DTO Framework&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The framework enables the scenario above by using special objects – self tracking DTOs. The server works with the POCOs as usual but when it needs to send an entity to the client it uses a different object (a DTO).It implements the same interface but in addition provide special functionality:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It Populates itself by a given server entity. &lt;/li&gt;    &lt;li&gt;Creates a new server side entity that contains its own value – by the common interface. &lt;/li&gt;    &lt;li&gt;Applies the modification made on it on a given server side object. &lt;/li&gt;    &lt;li&gt;&lt;u&gt;Bonus&lt;/u&gt;: INotifyPropertyChange – implemented by the DTO implements so if you use WPF you get it out of the box. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The framework provides two two core interfaces:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1. The ISelfTrackingDataTransferObject interface&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Provides the self tracking DTO needed functionality:&lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;void Populate(T entity)&lt;/em&gt;&lt;strong&gt; -&lt;/strong&gt; Populates the DTO object by the given entity.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;T Clone(bool getOriginalValue)&lt;/em&gt;&lt;strong&gt; &lt;/strong&gt;- Creates a DTO clone - Server side object that holds the same value as the DTO.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;void ApplyChanges(T enitity) &lt;/em&gt;- Simulate the changes made on the DTO object on the given entity (&amp;quot;plays&amp;quot; the changes).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2. The IDtoInstanceCreator interface&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;ISelfTrackingDataTransferObject&amp;lt;T&amp;gt; CreateDtoInstance&amp;lt;T&amp;gt;(T entity) - &lt;/em&gt;creates a new DTO instance by T and a given entity.&lt;/p&gt;  &lt;p&gt;The class that implements this interface is the DTO factory – it create DTO instance by using the two parameters (T) and specific entity object. Note: if we use inheritance some times entity type is&amp;#160; derive from T and we need to create the DTO instance by the entity type.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This example is part of the unit tests in the source, you can download and run it. I use Unity as my IoC so I use the UnityDataTransferObjectBase but it’s not mandatory, you can use the SelfTrackingDataTransferObjectBase as base class of the DTO object instead.&lt;/p&gt;  &lt;p&gt;We have a simple entity that inherits from base class and has a matching interface:&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; ISimpleObject : IObjectBase&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Id { get; set; }&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name { get; set; }&lt;br /&gt;   }&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ObjectBase : IObjectBase&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Id { get; set; }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; SimpleObject : ObjectBase ,ISimpleObject&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name { get; set; }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Now let’s look how at the DTO implementation:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[DataContract]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; SimpleObjectDto : UnitySelfTrackingDataTransferObjectBase&amp;lt;ISimpleObject&amp;gt;, ISimpleObject&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; SimpleObjectDto(IUnityContainer unityContainer) : &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;(unityContainer) { }&lt;br /&gt;    &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; ISimpleObject Members&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; _Id;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; _Name;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Id&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _Id;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            Set(&lt;span style="color:#006080;"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; _Id, &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _Name;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            Set(&lt;span style="color:#006080;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; _Name, &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SpecificPopulate(ISimpleObject entity, IDataTrasferObjectToEntityMapper dataTrasferObjectToEntityMapper)&lt;br /&gt;    {&lt;br /&gt;        _Id = entity.Id;&lt;br /&gt;        _Name = entity.Name;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SpecificGetValue(ISimpleObject entity, &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; getOriginalValue, IDataTrasferObjectToEntityMapper dataTrasferObjectToEntityMapper)&lt;br /&gt;    {&lt;br /&gt;        entity.Id = RetrievePropertyValue&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(&lt;span style="color:#006080;"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, getOriginalValue);&lt;br /&gt;        entity.Name = RetrievePropertyValue&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color:#006080;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;, getOriginalValue);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SpecificApplyChanges(ISimpleObject entity, IDataTrasferObjectToEntityMapper dataTrasferObjectToEntityMapper)&lt;br /&gt;    {&lt;br /&gt;    }     &lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Building the DTO is a technical action (no need to think here), in the source I have a readme guide that explains how do it and examples for each of the possible scenarios:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Entity holds only simple types. &lt;/li&gt;

  &lt;li&gt;Entity holds a reference to an Entity. &lt;/li&gt;

  &lt;li&gt;Entity holds a list of entities. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we implement the IDtoInstanceCreator interface, using unity. ( I use unity singleton which is just a singleton object holding UnityContainer)&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; MyDtoInstanceCreator : IDtoInstanceCreator&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; IDtoInstanceCreator Members&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ISelfTrackingDataTransferObject&amp;lt;T&amp;gt; CreateDtoInstance&amp;lt;T&amp;gt;(T entity)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (ISelfTrackingDataTransferObject&amp;lt;T&amp;gt;)UnitySingleton.Instance.UnityContainer.Resolve&amp;lt;T&amp;gt;(DataTransferObjectsTester.STR_DTO);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Setup our container:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;UnitySingleton.Instance.UnityContainer.RegisterInstance&amp;lt;IDtoInstanceCreator&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;  MyDtoInstanceCreator());&lt;br /&gt;UnitySingleton.Instance.UnityContainer.RegisterInstance&amp;lt;IUnityContainer&amp;gt;(UnitySingleton.Instance.UnityContainer);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;//concrete types&lt;/span&gt;&lt;br /&gt;UnitySingleton.Instance.UnityContainer.RegisterType&amp;lt;ISimpleObject, SimpleObject&amp;gt;();&lt;br /&gt;&lt;span style="color:#008000;"&gt;//DTOS&lt;/span&gt;&lt;br /&gt;UnitySingleton.Instance.UnityContainer.RegisterType&amp;lt;ISimpleObject, SimpleObjectDto&amp;gt;(STR_DTO);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Now we are ready to go!&lt;/p&gt;

&lt;p&gt;First loading and sending the entity to the client:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;ISimpleObject serverSideSimpleObject = LoadSimpleObject();&lt;br /&gt;IDtoInstanceCreator dtoCreator = UnitySingleton.Instance.UnityContainer.Resolve&amp;lt;IDtoInstanceCreator&amp;gt;();&lt;br /&gt;ISelfTrackingDataTransferObject&amp;lt;ISimpleObject&amp;gt; dtoObject = dtoCreator.CreateDtoInstance&amp;lt;ISimpleObject&amp;gt;(serverSideSimpleObject);&lt;br /&gt;dtoObject.Populate(serverSideSimpleObject);&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; dtoObject;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The client gets the DTO and ,modifies it and send it back to the server.The server is updates the entity state in data base (this is done inside ORM context scope):&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (IContext context = GetORMContext())&lt;br /&gt;{&lt;br /&gt;   ISimpleObject serverSide =  dtobject.Clone(&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;); &lt;span style="color:#008000;"&gt;//server side object holding the original values&lt;/span&gt;&lt;br /&gt;   context.Attach(serverSide); &lt;span style="color:#008000;"&gt;// attach the server side instance to context.&lt;/span&gt;&lt;br /&gt;   dtobject.ApplyChanges(serverSide);&lt;br /&gt;   context.SaveChanges();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next Phases&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Code Generator to generate the DTO class from the server side – I’m on it… &lt;/li&gt;

  &lt;li&gt;Support more actions on the collection – currently supports only add and remove. &lt;/li&gt;

  &lt;li&gt;More… I am open to your suggestions. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Entity Framework 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EF4 that is currently in beta (part of VS 2010 beta) has a CTP with another very similar solution to the disconnected scenario (read about it &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee335715.aspx" target="_blank"&gt;here&lt;/a&gt;). This solution varies from the Self tracking DTO for example it uses the same objects in the client and server side. Note this solution is EF bound (cannot be used with other ORM) and currently it is only a CTP. In addition if you use Oracle DB you currently don’t have a working EF4 provider ( I believe this will change in the near future). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So that’s all, this code is open for you to use and upgrade.&lt;/p&gt;

&lt;p&gt;Download it from &lt;a href="http://selftrakingdto.codeplex.com/" target="_blank"&gt;SelfTrackingDTO in CodePlex&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cheers Offir.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=458359" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/DTO/default.aspx">DTO</category></item><item><title>Passing Event Handlers Over WCF</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2009/10/10/passing-event-handlers-over-wcf.aspx</link><pubDate>Sun, 11 Oct 2009 00:40:08 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:423492</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=423492</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2009/10/10/passing-event-handlers-over-wcf.aspx#comments</comments><description>&lt;p&gt;Hi&lt;/p&gt;  &lt;p&gt;It’s been a really long time since my last post. Lately I been working on a POC aimed&amp;#160; at building an infrastructure layer for accessing the data in the application. Currently this layer is based on Nhibernate and supports several functionalities like WCF interface and more. As part of the POC I encountered a problem and managed to give it a satisfying solution. I want to share the problem and the solution with you.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I was building a complex object hierarchy – each object has a reference to a different object or to a collection of other objects. I build this object hierarchy in the server side and pass it on to the client (using WCF). The problem was that part of my logic needed to use the objects events (to be specific I use the ProperyChanged event). Objects in the objects tree are subscribers of the other objects events, to be more specific each object is registered to the PropertyChange event of its child objects.&lt;strong&gt;The events should be fired only on the client side but the registration is done in the server side. &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I know the &lt;a href="http://msdn.microsoft.com/en-us/library/system.delegate.aspx"&gt;Delegate&lt;/a&gt; object is serializable&amp;#160; so first I tried using the default WCF serializer – DataContractSerializer. I mark my class with the serializable attribute – i could not use DataContract attribute because you can only put [DataMemeber] on fields and properties (not events) .&lt;/p&gt;  &lt;p&gt;The code:&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[Serializable]&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ClassContainsEvents : INotifyPropertyChanged&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; INotifyPropertyChanged Members&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; properyName)&lt;br /&gt;       {&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (PropertyChanged != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;           {&lt;br /&gt;               PropertyChanged(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventArgs(properyName));&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;       &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; _testProperty;&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; TestProperty&lt;br /&gt;       {&lt;br /&gt;           get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _testProperty; }&lt;br /&gt;           set&lt;br /&gt;           {&lt;br /&gt;               _testProperty = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;               OnPropertyChanged(&lt;span style="color:#006080;"&gt;&amp;quot;TestProperty&amp;quot;&lt;/span&gt;);&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; RegisterEvent()&lt;br /&gt;       {&lt;br /&gt;           PropertyChanged += &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventHandler(TestClass_PropertyChanged);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; TestClass_PropertyChanged(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, PropertyChangedEventArgs e)&lt;br /&gt;       {&lt;br /&gt;           Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Property Changed: {0}&amp;quot;&lt;/span&gt;, e.PropertyName);&lt;br /&gt;       }&lt;br /&gt;    &lt;br /&gt;   }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Then I got SerializationException:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Type &amp;#39;System.DelegateSerializationHolder+DelegateEntry&amp;#39; with data contract name &amp;#39;DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System&amp;#39; is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer”. &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I tried to use XmlSerializer and didn’t get the exception I just got the object without handlers on the client side.&lt;/p&gt;

&lt;h5&gt;The Solution&lt;/h5&gt;

&lt;p&gt;This problem has several solutions each of them has their own advantages and disadvantages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution 1 – Use NetDataContractSerializer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This solution is the simplest one, just modify your WCF to use the NetDataContractSerializer (detailed description in the &lt;a href="http://www.pluralsight.com/community/blogs/aaron/archive/2006/04/21/22284.aspx"&gt;link&lt;/a&gt;) instead of the DataContractSerializer and it works like a charm. So this solution is really simple and quick, but the disadvantage in this solution is clear:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt; Using this serialzer binds the service to only for .NET client making the WCF service platform dependent. &lt;/li&gt;

  &lt;li&gt;This serialzer is much less efficient than the DataContractSerializer because it adds&amp;#160; CLR types meta data in addition to object data .&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution 2 – Use Serialize events&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The serialization process fires events throughout the process – we can hook the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializingattribute.aspx"&gt;OnDeserialized&lt;/a&gt; event (fired after the deserialize process finished) and reconnect the events subscribers. This solution has many disadvantages:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We have to save state (the subscribers data) in the object holding the event in addition to the event holding it’s handlers – redundancy. &lt;/li&gt;

  &lt;li&gt;Add specific logic to the object for serialization – in the object there is specific code for serialzation. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The solution in code (added the OnDeserialized method) :&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[DataContract]&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ClassContainsEvents : INotifyPropertyChanged&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; INotifyPropertyChanged Members&lt;br /&gt;&lt;br /&gt;       [OnDeserialized]&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ReconnectEvents(StreamingContext context)&lt;br /&gt;       {&lt;br /&gt;           PropertyChanged += &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventHandler(TestClass_PropertyChanged);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; properyName)&lt;br /&gt;       {&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (PropertyChanged != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;           {&lt;br /&gt;               PropertyChanged(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventArgs(properyName));&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;       &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; _testProperty;&lt;br /&gt;       [DataMember]&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; TestProperty&lt;br /&gt;       {&lt;br /&gt;           get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _testProperty; }&lt;br /&gt;           set&lt;br /&gt;           {&lt;br /&gt;               _testProperty = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;               OnPropertyChanged(&lt;span style="color:#006080;"&gt;&amp;quot;TestProperty&amp;quot;&lt;/span&gt;);&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; RegisterEvent()&lt;br /&gt;       {&lt;br /&gt;           PropertyChanged += &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventHandler(TestClass_PropertyChanged);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; TestClass_PropertyChanged(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, PropertyChangedEventArgs e)&lt;br /&gt;       {&lt;br /&gt;           Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Property Changed: {0}&amp;quot;&lt;/span&gt;, e.PropertyName);&lt;br /&gt;       }&lt;br /&gt;    &lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution 3 – Use the SerializableEventHandler&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This solution is an upgrade of solution 2: giving a generic way to save the handlers in a generic object called SerializableEventHandler. Saves the handlers only once – remove the redundancy. When you want or must use the DataContractSerializer for your own reasons you can use this generic class.&lt;/p&gt;

&lt;p&gt;So let’s look at the code – implementing INotifyPropertyChanged.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[DataMember]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; List&amp;lt;SerializableEventHandler&amp;lt;ClassContainsEvents, PropertyChangedEventArgs&amp;gt;&amp;gt; _notifyPropertyHandlers = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;SerializableEventHandler&amp;lt;ClassContainsEvents, PropertyChangedEventArgs&amp;gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged&lt;br /&gt;{&lt;br /&gt;    add&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        _notifyPropertyHandlers.Add(SerializableEventHandler.InitSerializableEventHandler&amp;lt;ClassContainsEvents, PropertyChangedEventArgs&amp;gt;(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;));&lt;br /&gt;    }&lt;br /&gt;    remove&lt;br /&gt;    {&lt;br /&gt;        _notifyPropertyHandlers.Remove(SerializableEventHandler.InitSerializableEventHandler&amp;lt;ClassContainsEvents, PropertyChangedEventArgs&amp;gt;(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; properyName)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_notifyPropertyHandlers != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; _notifyPropertyHandlers.Count &amp;gt; 0)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var handler &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; _notifyPropertyHandlers)&lt;br /&gt;        {&lt;br /&gt;            handler.Invoke(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventArgs(properyName));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;We define a List of SerializableEventHandler, and use &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163533.aspx"&gt;Event Accessors&lt;/a&gt; to override the += and –= operators.&lt;/p&gt;

&lt;p&gt;The firing event methods just runs on the handlers list and call the Invoke method.&lt;/p&gt;

&lt;p&gt;So let’s look at the SerializableEventHandler code:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[DataContract(IsReference = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; SerializableEventHandler&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; SerializableEventHandler&amp;lt;TT, TTEventArgs&amp;gt; InitSerializableEventHandler&amp;lt;TT, TTEventArgs&amp;gt;(Delegate handler)&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; TTEventArgs : EventArgs&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SerializableEventHandler&amp;lt;TT, TTEventArgs&amp;gt;()&lt;br /&gt;        {&lt;br /&gt;            MethodName = handler.Method.Name,&lt;br /&gt;            Traget = (TT)handler.Target&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[DataContract(IsReference = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; SerializableEventHandler&amp;lt;T, TEventArgs&amp;gt; : SerializableEventHandler&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; TEventArgs : EventArgs&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; MethodInfo _handlerMethodInfo = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; T Traget { get; set; }&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; MethodName { get; set; }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Invoke(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, TEventArgs args)&lt;br /&gt;    {&lt;br /&gt;        initMethodInfo();&lt;br /&gt;        _handlerMethodInfo.Invoke(Traget, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[] { sender, args });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; initMethodInfo()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_handlerMethodInfo == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            _handlerMethodInfo = Traget.GetType().GetMethod(MethodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Equals(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (obj &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; SerializableEventHandler&amp;lt;T, TEventArgs&amp;gt;)&lt;br /&gt;        {&lt;br /&gt;            var handler = obj &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; SerializableEventHandler&amp;lt;T, TEventArgs&amp;gt;;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Traget.Equals(handler.Traget) &amp;amp;&amp;amp; MethodName.Equals(handler.MethodName);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color:#006080;"&gt;&amp;quot;Cannot comper to other types than SerializableEventHandler&amp;lt;T,TEventArgs&amp;gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; GetHashCode()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Traget.GetHashCode() + MethodName.GetHashCode();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Note the class gets two generic types:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;T&lt;/strong&gt; – The type of the instance holding the handler method. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;TEventArg&lt;/strong&gt; – The type of the second parameter in the handler method. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We save the method name as string – because we can’t serialize the MethodInfo object, the reason is the delegate holds the &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx"&gt;MethodInfo&lt;/a&gt; member that is marked as serializable but holds &lt;strong&gt;RuntimeMethodInfo type instance &lt;/strong&gt;which is internal and has only private constructor (you cannot create instance). So we use reflection to invoke the method but the Method info retrieval will be called only once in the first call – we save a MethodInfo as a member after he first Invoke call. &lt;/p&gt;

&lt;p&gt;The class full code:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[DataContract]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ClassContainsEvents : INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; _testProperty;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; Guid _id;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ClassContainsEvents()&lt;br /&gt;    {&lt;br /&gt;        Id = Guid.NewGuid();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; Properties&lt;br /&gt;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Guid Id&lt;br /&gt;    {&lt;br /&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _id; }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _id = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;            OnPropertyChanged(&lt;span style="color:#006080;"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; TestProperty&lt;br /&gt;    {&lt;br /&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _testProperty; }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _testProperty = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;            OnPropertyChanged(&lt;span style="color:#006080;"&gt;&amp;quot;TestProperty&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; EventHandlers&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; RegisterEvent()&lt;br /&gt;    {&lt;br /&gt;        PropertyChanged += &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventHandler(TestClass_PropertyChanged);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; UnregisterEvent()&lt;br /&gt;    {&lt;br /&gt;        PropertyChanged -= &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventHandler(TestClass_PropertyChanged);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; TestClass_PropertyChanged(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, PropertyChangedEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Property Changed: {0}&amp;quot;&lt;/span&gt;, e.PropertyName);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; INotifyPropertyChanged Members&lt;br /&gt;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; List&amp;lt;SerializableEventHandler&amp;lt;ClassContainsEvents, PropertyChangedEventArgs&amp;gt;&amp;gt; _notifyPropertyHandlers = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;SerializableEventHandler&amp;lt;ClassContainsEvents, PropertyChangedEventArgs&amp;gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged&lt;br /&gt;    {&lt;br /&gt;        add&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            _notifyPropertyHandlers.Add(SerializableEventHandler.InitSerializableEventHandler&amp;lt;ClassContainsEvents, PropertyChangedEventArgs&amp;gt;(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;));&lt;br /&gt;        }&lt;br /&gt;        remove&lt;br /&gt;        {&lt;br /&gt;            _notifyPropertyHandlers.Remove(SerializableEventHandler.InitSerializableEventHandler&amp;lt;ClassContainsEvents, PropertyChangedEventArgs&amp;gt;(&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; properyName)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_notifyPropertyHandlers != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; _notifyPropertyHandlers.Count &amp;gt; 0)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var handler &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; _notifyPropertyHandlers)&lt;br /&gt;            {&lt;br /&gt;                handler.Invoke(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventArgs(properyName));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Equals(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (obj &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; ClassContainsEvents)&lt;br /&gt;        {&lt;br /&gt;            var cce = obj &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; ClassContainsEvents;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Id.Equals(cce.Id);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color:#006080;"&gt;&amp;quot;Cannot comper to other types than ClassContainsEvents&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; GetHashCode()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Id.GetHashCode();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Limitation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;T must be serializable. &lt;/li&gt;

  &lt;li&gt;In order to use –= in the client side the class T must implement Equal method because the instance of the Target is different between the client and server. &lt;/li&gt;

  &lt;li&gt;We have to hold List of SerializableEventHandler&amp;#160; for each target of type(T) we want to support containing handlers (act as a Target) – the better solution is to set T to be one common base class that all event subscribers derive from. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Summery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well in this post I gave 3 solutions to a the passing event handlers problem, this problem is not common (it took me 6 years before I first encounter it) but the solutions are helping us understand other issues regarding serialization. I recommend reading about the different WCF serializer types see the &lt;a href="http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/"&gt;link&lt;/a&gt;, and you may use one of the ideas above to solve other issues. I’ll be glad to hear your comments.&lt;/p&gt;

&lt;p&gt;Cheers, Offir.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=423492" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Generic/default.aspx">Generic</category></item><item><title>Layered Application wannabe</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2009/02/22/layered-application-wannabe.aspx</link><pubDate>Mon, 23 Feb 2009 00:05:20 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:234072</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=234072</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2009/02/22/layered-application-wannabe.aspx#comments</comments><description>&lt;p&gt;Hi it&amp;#39;s been a while since my last post (just had nothing interesting to write about). In this post I wanted to share an issue I encountered recently while reviewing a medium scale web application.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Layered Application&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This is a common architecture of an enterprise application that has a large number of components (read about it &lt;a href="http://msdn.microsoft.com/en-us/library/ms978678.aspx" target="_blank"&gt;here&lt;/a&gt;). &lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I was told that the web application I was reviewing conformed with the &lt;a title="http://msdn.microsoft.com/en-us/library/ms978689.aspx" href="http://msdn.microsoft.com/en-us/library/ms978689.aspx"&gt;Three-Layered Services Application pattern&lt;/a&gt;. I started taking a closer look at the code and found that the web app had one solution that contains a web site and three class library projects: &lt;strong&gt;BL&lt;/strong&gt; (Business Logic), &lt;strong&gt;DAL&lt;/strong&gt; (Data access Layer) and &lt;strong&gt;Common&lt;/strong&gt;.&amp;nbsp; It seemed like the layers of the app were really independent and separated, until I encountered something like:&lt;/p&gt; &lt;div style="border-right:gray 1px solid;padding-right:4px;border-top:gray 1px solid;padding-left:4px;font-size:8pt;padding-bottom:4px;margin:20px 0px 10px;overflow:auto;border-left:gray 1px solid;width:97.5%;cursor:text;max-height:200px;line-height:12pt;padding-top:4px;border-bottom:gray 1px solid;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;background-color:#f4f4f4;"&gt; &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomeLogic() &lt;span style="color:#008000;"&gt;//Some Input&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;{&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    DataSet entitiesDs = DAL.ReadEntities();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt;(DataRow dr im entitiesDs.Tables[0].Rows) &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        runSomeAction(dr[&lt;span style="color:#006080;"&gt;&amp;quot;entityId&amp;quot;&lt;/span&gt;])&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    &lt;span style="color:#008000;"&gt;//More code&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The above is&amp;nbsp; a simplified example of code in the BL assembly (Business Logic layer) - It uses the DAL in order to read the entities from data base. &lt;/p&gt;
&lt;p&gt;So what&amp;#39;s wrong with this code ?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The BL is using the first table from the data set &lt;strong&gt;assuming&lt;/strong&gt; it exists and contains the right data - can cause runtime error. 
&lt;li&gt;In the Data Row object we read column name &amp;quot;entityId&amp;quot; (even if it is const string) - causing two problems: 
&lt;ul&gt;
&lt;li&gt;can cause runtime error if the column doesn&amp;#39;t exists. 
&lt;li&gt;dr[&amp;quot;columnName&amp;quot;] returns an object we need to cast or parse - this can cause invalid cast exception and performance issues in case we Parse the object result. &lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;The use of DataSet - first I must confess that &lt;strong&gt;I HATE DataSets&lt;/strong&gt; because: 
&lt;ul&gt;
&lt;li&gt;it uses a large amount of memory that in most cases contains more then we need (especially when we build a layered application) like relations. 
&lt;li&gt;it is &lt;strong&gt;weak type&lt;/strong&gt; (the opposite of &lt;strong&gt;strong type&lt;/strong&gt;) you just don&amp;#39;t know what you have - you just can&amp;#39;t understand from your code what the data set contains causing maintenance to be very hard, essentially requiring you to debug to understand the code.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The main issue: We don&amp;#39;t really have layer separation --&amp;gt; &lt;/strong&gt;changes in the Data Base schema may cause changes both the Business Layer (BL) and in the data access layer (DAL).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Layered Application Benefits&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I think back to the years I develop without Layer separation, I just can&amp;#39;t understand how I could do it. Layer separation seems so natural and so required now. There are a lot of benefits (I&amp;#39;ll try to give most of them)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Maintenance&lt;/strong&gt; - in case of schema change we need to modify only the Data Layer. 
&lt;li&gt;&lt;strong&gt;Reusable&lt;/strong&gt; - Blocks of functionality are modular and can be used in other applications due to good separation and abstraction. 
&lt;li&gt;&lt;strong&gt;Readable&lt;/strong&gt; - good separation cause clear code. The objects that pass between the layers are simple (containing no logic) making the function flow clear and understandable. 
&lt;li&gt;&lt;strong&gt;Testable&lt;/strong&gt; - if you use TDD you have to keep this separation because you want to test only a specific unit (in the BL for example) - no separation makes this task impossible. 
&lt;li&gt;&lt;strong&gt;Flexibility&lt;/strong&gt; - replacing Layers while using the same interface is a simple task when the separation is complete. 
&lt;li&gt;&lt;strong&gt;Scalability&lt;/strong&gt; - when the data objects are simple and small size we can easily deal with them in chunks, clear code allows developing scalable application.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The solution is to &lt;strong&gt;use simple data container objects to pass between layers&lt;/strong&gt; (&amp;quot;object model&amp;quot;). In most cases I think they shouldn&amp;#39;t hold any logic - leave the logic to the BL layer.&lt;/p&gt;
&lt;p&gt;You already know what I think of DataSets, but still there are some cases (not many...) we need to use them. For example - a loose coupled functionality (when we don&amp;#39;t know and care what is returned and just want to bind it to a data grid in our UI). but if out BL needs to implement some functionality using the DataSet (like in the example above) - we must make &lt;u&gt;only the data we use&lt;/u&gt; strong typed and init the objects strong type properties in the Data layer. Inherit from DataSet and add the needed properties for your logic.&lt;/p&gt;
&lt;p&gt;For example the solution for the code above:&lt;/p&gt;
&lt;div style="border-right:gray 1px solid;padding-right:4px;border-top:gray 1px solid;padding-left:4px;font-size:8pt;padding-bottom:4px;margin:20px 0px 10px;overflow:auto;border-left:gray 1px solid;width:97.5%;cursor:text;max-height:200px;line-height:12pt;padding-top:4px;border-bottom:gray 1px solid;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;background-color:#f4f4f4;"&gt;
&lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; EntityDataSet: DataSet&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;{&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; EntityTableIndex {get; set;}&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DataTable EntityDataTable &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        get &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        { &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Tables[EntityTableIndex];&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; EntityIdColumnName {get; set;}&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;and the function looks like this:&lt;/p&gt;
&lt;div style="border-right:gray 1px solid;padding-right:4px;border-top:gray 1px solid;padding-left:4px;font-size:8pt;padding-bottom:4px;margin:20px 0px 10px;overflow:auto;border-left:gray 1px solid;width:97.5%;cursor:text;max-height:200px;line-height:12pt;padding-top:4px;border-bottom:gray 1px solid;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;background-color:#f4f4f4;"&gt;
&lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomeLogic() &lt;span style="color:#008000;"&gt;//some input&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;{&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    EntityDataSet entityDs = DAL.ReadEntities();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt;(DataRow dr &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; entityDs.EntityDataTable.Rows) &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        doSomeLogic(dr[entityDs.EntityIdColumnName]);&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    &lt;span style="color:#008000;"&gt;//more code&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Summery&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To conclude using layered application pattern can be very profitable. Ask yourself is you application architecture is really layered application, or just &lt;strong&gt;layered application wannabe&lt;/strong&gt;. Using three separate projects is just not enough, make sure that changing the data base schema will cause only a change in the Data access layer and changing the business logic will need only modification in your business logic layer.&lt;/p&gt;
&lt;p&gt;Cheers Offir :-) &lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=234072" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/layered+application/default.aspx">layered application</category></item><item><title>T3 Service Studio - The ultimate tool for testing your web services and WCF services</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2008/11/10/t3-service-studio-the-ultimate-tool-for-testing-your-web-services-and-wcf-services.aspx</link><pubDate>Mon, 10 Nov 2008 18:39:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:164004</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=164004</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2008/11/10/t3-service-studio-the-ultimate-tool-for-testing-your-web-services-and-wcf-services.aspx#comments</comments><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;During my work I developed many web services and now WCF services, I encountered a very useful tool called &lt;a href="http://www.codeplex.com/WebserviceStudio" target="_blank"&gt;Web Service studio&lt;/a&gt; which allows invoking web method without writing any code - gives the ability to test web service without any client code.&lt;/p&gt;
&lt;p&gt;The tool was great but far from perfect: I encountered some bugs, the UI was in my opinion not as clear and comfortable as it could be and the main problem was &lt;strong&gt;not supporting WCF.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So me and my friends: Ami Yolovich and Anat Katz started developing in our spare time our own web service studio - we called him&lt;strong&gt; T3 Service Studio&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In&amp;nbsp;the past few weeks this tool become very useful for us (using it for WCF testing) so I decided to upload it to the web, it can be useful to many others and I&amp;#39;ll be glad to get your comments and bug reports.&lt;/p&gt;
&lt;p&gt;So here it is:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/oshvartz/WindowsLiveWriter/T3ServiceStudioTheultimatetoolfortesting_11564/image_2.png"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="387" alt="image" src="http://blogs.microsoft.co.il/blogs/oshvartz/WindowsLiveWriter/T3ServiceStudioTheultimatetoolfortesting_11564/image_thumb.png" width="552" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Partial feature list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WCF support - include TCP binding.&lt;/li&gt;
&lt;li&gt;Multi sessions UI.&lt;/li&gt;
&lt;li&gt;Copy paste of requests object.&lt;/li&gt;
&lt;li&gt;DataSet viewer.&lt;/li&gt;
&lt;li&gt;XmlNode viewer.&lt;/li&gt;
&lt;li&gt;Much more...&lt;/li&gt;&lt;/ul&gt;
&lt;h6&gt;Requirements&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h6&gt;&amp;nbsp;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=AB99342F-5D1A-413D-8319-81DA479AB0D7&amp;amp;displaylang=en" target="_blank"&gt;Microsoft .NET Framework 3.5 Service Pack 1&lt;/a&gt; installed.&lt;/h6&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/files/folders/oshvartz/entry164001.aspx" target="_blank"&gt;Download T3 Service Studio&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cheers Offir&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=164004" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Web+Service/default.aspx">Web Service</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/WCF/default.aspx">WCF</category></item><item><title>Using Generic Parameter as an Attribute constructor parameter</title><link>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2008/10/31/using-generic-parameter-as-an-attribute-constructor-parameter.aspx</link><pubDate>Fri, 31 Oct 2008 17:44:56 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:160418</guid><dc:creator>Offir Shvartz</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/oshvartz/rsscomments.aspx?PostID=160418</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/oshvartz/archive/2008/10/31/using-generic-parameter-as-an-attribute-constructor-parameter.aspx#comments</comments><description>&lt;p&gt;Hi all, it&amp;#39;s been long while since the last time I wrote (I just wasn&amp;#39;t in the mood....). recently I encountered something interesting in my opinion related to generic so I wanted to share it and hear your comments.&lt;/p&gt; &lt;p&gt;It all started with a simple task: my task was to implement generic custom control (Win Forms) that contains PropertyGrid and sets the selected object property to given object. the additional requirement was that in case the object has default constructor allowing creating new instance on the given object.&lt;/p&gt; &lt;p&gt;the control implementation is very simple (my example is in form only for testing purpose): &lt;/p&gt; &lt;div style="border-right:gray 1px solid;padding-right:4px;border-top:gray 1px solid;padding-left:4px;font-size:8pt;padding-bottom:4px;margin:20px 0px 10px;overflow:auto;border-left:gray 1px solid;width:97.5%;cursor:text;line-height:12pt;padding-top:4px;border-bottom:gray 1px solid;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;background-color:#f4f4f4;max-height:200px;"&gt; &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Form1 : Form&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;{&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; System.Windows.Forms.PropertyGrid propertyGrid1;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; m_obj;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Form1(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; obj)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        InitializeComponent();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        m_obj = obj; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Form1_Load(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    {          &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        propertyGrid1.SelectedObject = m_obj;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In order to implement the instance creation part I implemented before my own UITypeEditor, I called it GenericTypeUIEditor and by adding the EditAttribute to the selected field the property grid object apply my editor to the object (read about it &lt;a href="http://msdn.microsoft.com/en-us/library/ms171840.aspx" target="_blank"&gt;Walkthrough: Implementing a UI Type Editor&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;My GenericTypeUIEditor implementation was very simple just calling the Activator.CreateInstance&amp;lt;T&amp;gt;()&lt;/p&gt;
&lt;div style="border-right:gray 1px solid;padding-right:4px;border-top:gray 1px solid;padding-left:4px;font-size:8pt;padding-bottom:4px;margin:20px 0px 10px;overflow:auto;border-left:gray 1px solid;width:97.5%;cursor:text;line-height:12pt;padding-top:4px;border-bottom:gray 1px solid;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;background-color:#f4f4f4;max-height:200px;"&gt;
&lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; GenericTypeUIEditor&amp;lt;T&amp;gt; : UITypeEditor &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T:&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;()&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;{&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;  &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; UITypeEditorEditStyle.Modal;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Activator.CreateInstance&amp;lt;T&amp;gt;();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I wrote this UITypeEditor a while ago and it works perfectly for many object types just by adding to and property the attribute:&lt;/p&gt;
&lt;div style="border-right:gray 1px solid;padding-right:4px;border-top:gray 1px solid;padding-left:4px;font-size:8pt;padding-bottom:4px;margin:20px 0px 10px;overflow:auto;border-left:gray 1px solid;width:97.5%;cursor:text;line-height:12pt;padding-top:4px;border-bottom:gray 1px solid;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;height:46px;background-color:#f4f4f4;max-height:200px;"&gt;
&lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;[Editor(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(GenericTypeUIEditor&amp;lt;MyClass&amp;gt;), &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(UITypeEditor))]&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; MyClass MyClass {get;set;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I wanted a control that supports all types (that implements default constructor) so I wrote generic value wrapper to hold the object and added my generic attribute.&lt;/p&gt;
&lt;div style="border-right:gray 1px solid;padding-right:4px;border-top:gray 1px solid;padding-left:4px;font-size:8pt;padding-bottom:4px;margin:20px 0px 10px;overflow:auto;border-left:gray 1px solid;width:97.5%;cursor:text;line-height:12pt;padding-top:4px;border-bottom:gray 1px solid;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;background-color:#f4f4f4;max-height:200px;"&gt;
&lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ValueWrapper&amp;lt;T&amp;gt; &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T:&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;()&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;{&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ValueWrapper(T val)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        Value = val;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    [TypeConverter(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(ExpandableObjectConverter))]&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    [Editor(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(GenericTypeUIEditor&amp;lt;T&amp;gt;), &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(UITypeEditor))]&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; T Value { get; set; }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;So the form constructor parameter gets the wrapper object, you can create new instance of this generic type in runtime, in this stage I thought I was done and the code is very clear but then...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;error CS0416&lt;/strong&gt;: &amp;#39;PropertyGridTester.GenericTypeUIEditor&amp;lt;T&amp;gt;&amp;#39;: an attribute argument cannot use type parameters.&lt;/p&gt;
&lt;p&gt;I was really surprised because I didn&amp;#39;t understand why?&lt;/p&gt;
&lt;p&gt;I looked around, and I knew that generic type is resolved during runtime (read about it in the next link:&lt;a href="http://msdn.microsoft.com/en-us/library/f4a6ta2h(VS.80).aspx" target="_blank"&gt;Generics in the Runtime&lt;/a&gt;), but what about attribute or in my case the parameter of attribute. during my search I discovered that &lt;a href="http://msdn.microsoft.com/en-us/library/t9h2ax10.aspx" target="_blank"&gt;Attributes are not allowed to be generic types&lt;/a&gt;. The only reason I can think of is that a generic type parameter is resolved at runtime. However, an attribute parameter must be resolved at compile time. Therefore, you cannot use a generic type parameter as an argument to an attribute.&lt;/p&gt;
&lt;p&gt;So still I needed to solve my problem, well my workaround was to modified my UIEditor: removing the Generics type and using the ITypeDescriptorContext parameter in the method:&lt;/p&gt;
&lt;p&gt;public override object EditValue(&lt;strong&gt;System.ComponentModel.ITypeDescriptorContext context&lt;/strong&gt;, IServiceProvider provider, object value)&lt;/p&gt;
&lt;p&gt;By using the Instance property retrieving the generic type:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;context.Instance.GetType().GetGenericArguments()[0]&lt;/strong&gt; - the first generic type of the context instance&lt;/p&gt;
&lt;p&gt;here is the new code:&lt;/p&gt;
&lt;div style="border-right:gray 1px solid;padding-right:4px;border-top:gray 1px solid;padding-left:4px;font-size:8pt;padding-bottom:4px;margin:20px 0px 10px;overflow:auto;border-left:gray 1px solid;width:97.5%;cursor:text;line-height:12pt;padding-top:4px;border-bottom:gray 1px solid;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;height:338px;background-color:#f4f4f4;max-height:200px;"&gt;
&lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; GenericTypeUIEditor : UITypeEditor&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;{&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; UITypeEditorEditStyle.Modal;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;            Type valType = context.Instance.GetType().GetGenericArguments()[0];&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Activator.CreateInstance(valType);&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;and removed the &amp;lt;T&amp;gt; from the attribute parameter and it works perfectly.&lt;/p&gt;
&lt;p&gt;So to conclude attributes cannot be generics (maybe in .NET framework 4.0) because they are resolved in compilation time and generic types during runtime.&lt;/p&gt;
&lt;p&gt;That&amp;#39;s all for now, Offir.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=160418" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Dev/default.aspx">Dev</category><category domain="http://blogs.microsoft.co.il/blogs/oshvartz/archive/tags/Generic/default.aspx">Generic</category></item></channel></rss>