<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-23538096</id><updated>2012-01-22T22:44:50.965-03:00</updated><category term='WF'/><category term='Visual Studio'/><category term='.Net 3.0'/><category term='WCF'/><category term='Entlib'/><category term='DSL'/><category term='security'/><category term='Sharepoint'/><category term='CCF'/><category term='Office add-ins'/><category term='nant'/><category term='Jquery'/><category term='code analysis'/><category term='testing'/><category term='wix'/><category term='WPF'/><category term='CodeCamp'/><category term='blogs'/><category term='Cloud'/><title type='text'>Soledad Pano's Blog</title><subtitle type='html'>Just technical stuff.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>47</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-23538096.post-8077377892695095630</id><published>2012-01-22T22:44:00.000-03:00</published><updated>2012-01-22T22:44:50.974-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><title type='text'>Media from Sharepoint to the Cloud</title><content type='html'>&lt;p&gt;On &lt;a href="http://weblogs.asp.net/spano/archive/2012/01/12/media-processing-component-for-sharepoint.aspx"&gt;my last post&lt;/a&gt; I talked about a media processing component developed for Sharepoint 2010. Besides the processing features (video encoding, thumbnail generation, validations, etc…) there was an asset storage manager that enabled us to store the files on a configurable place, inside or outside Sharepoint. I said we initially started with three storage flavors: a Sharepoint library, an FTP server or a shared folder/virtual directory.&lt;/p&gt;  &lt;p&gt;My co-worker &lt;a href="http://dgoins.wordpress.com/2012/01/19/using-amazon-s3-as-a-media-hosting-option-for-sharepoint-2010/"&gt;Dwight Goins&lt;/a&gt; has extended the options by adding a cloud based storage manager. In this case he uses the &lt;a href="http://aws.amazon.com/s3/"&gt;Amazon Simple Storage Service (Amazon S3)&lt;/a&gt;, which resulted in a great performing storage solution. In &lt;a href="http://dgoins.wordpress.com/2012/01/19/using-amazon-s3-as-a-media-hosting-option-for-sharepoint-2010/"&gt;his post&lt;/a&gt;, he digs deeper in the issues of storing BLOBs (Binary Large Objects) in Sharepoint and the solution that Sharepoint provides, SQL’s &lt;a href="http://technet.microsoft.com/en-us/library/ff628583.aspx"&gt;Remote BLOB Storage&lt;/a&gt; (RBS). Then he talks about our solution and the details of the AmazonS3 client. &lt;a href="http://dgoins.wordpress.com/2012/01/19/using-amazon-s3-as-a-media-hosting-option-for-sharepoint-2010/"&gt;Check this out&lt;/a&gt;! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-8077377892695095630?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/8077377892695095630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=8077377892695095630&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/8077377892695095630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/8077377892695095630'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2012/01/media-from-sharepoint-to-cloud.html' title='Media from Sharepoint to the Cloud'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-4097080241407195991</id><published>2012-01-12T14:33:00.000-03:00</published><updated>2012-01-12T14:33:00.693-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><title type='text'>Media Processing Component for Sharepoint</title><content type='html'>I have been working recently on the task of building a media processing component for the Sharepoint project I am working on. The requirements for the component are more or less the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Site Content Creators must be able to upload media assets (images, audio and video) to a Sharepoint list, and these assets must accomplish certain validation rules. &lt;/li&gt;&lt;li&gt;The final destination where the assets are saved after upload must be configurable and extensible. To begin with, we are supporting saving to a Sharepoint library, a network share or an FTP server. &lt;/li&gt;&lt;li&gt;The videos must be encoded to MP4 format, and thumbnail and poster images must be generated. The encoding process must be run asynchronously and the user must be notified by email when it is finished. &lt;/li&gt;&lt;/ul&gt;Today I want to share the design of the component and the key pieces of code. I will focus on the video upload process which is the more complex one because of the encoding. Audio and image uploads are more straightforward.&lt;br /&gt;The main parts that build the solution are: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Custom Upload Process&lt;/strong&gt;: This is the front end of the solution. It consists of a custom list with a custom upload form. The list has the link to the media file and more metadata fields (title, author, date, keywords, etc). When you click on create a new item on the list the custom upload form is opened and you can browse for a file to upload. The form has the required validation logic and it serves to save the assets to the configured location, which can be a Sharepoint library or an external location, like File System or FTP server. When the upload finishes you are redirected to the list item edit form so you can enter the metadata. The experience is similar to uploading a file to a Sharepoint document library. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Media Processing Backend Process&lt;/strong&gt;: This consists of a timer job that queries the Media Assets list for items to process. It encodes the videos, generates thumbnail and poster images and uploads everything to the final destination. Finally, it notifies the user of the result of the process by email. For the video encoding we used the Microsoft Expression Encoder SDK. As I will explain later, this SDK cannot be used inside a Sharepoint process, so it runs in a separated process that is invoked from the timer job. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Storage Manager&lt;/strong&gt;: this is a flexible and extensible component that abstracts the logic of saving (and deleting) a file to the final location depending on the flavor chosen thru configuration (File System, Sharepoint library or FTP). This component is used both by the front end upload mechanism and the back end media processing job. &lt;/li&gt;&lt;/ol&gt;Here is a diagram of the overall design for the video processing:&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/-DSU_vrhuyJ8/Tw8VRm61ByI/AAAAAAAADjY/iDcEsFlV3Rw/s1600-h/MediaProcessing%25255B3%25255D.png"&gt;&lt;img alt="MediaProcessing" border="0" height="763" src="http://lh4.ggpht.com/-q8zy4wchepQ/Tw8VS2h9VTI/AAAAAAAADjc/qHUjlvHC5Ek/MediaProcessing_thumb%25255B3%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="MediaProcessing" width="825" /&gt;&lt;/a&gt;&lt;br /&gt;Now I will explain in a little more detail each component:&lt;br /&gt;&lt;h4&gt;&lt;u&gt;1. Custom Upload Process&lt;/u&gt;&lt;/h4&gt;&lt;h5&gt;The Media Assets List&lt;/h5&gt;This is a Sharepoint list that stores the metadata of the media assets, but not the asset itself (the assets are stored in the definite storage, which can be a Sharepoint assets library, a network shared folder, or an FTP server). The list is based on three custom content types, WebVideo, WebAudio and WebImage, all three inheriting from a base MediaAsset content type. This content type has the required fields for saving the asset metadata. The more important ones for the processing being: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Location&lt;/strong&gt;: the URL of the asset in its definite location (in the example on the picture it is a sharepoint library called MediaAssetsLib). &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Temp Location&lt;/strong&gt;: As videos needs asynchronous processing, they are saved in a temporary location on upload. It is the timer job that uploads them to the definite location after encoding. The temp location is a shared folder on the network. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Processing Status&lt;/strong&gt;: It is &lt;em&gt;Success&lt;/em&gt; for assets successfully uploaded to the definite storage, &lt;em&gt;Pending&lt;/em&gt; for assets waiting for encoding in the back end process and &lt;em&gt;Error&lt;/em&gt; in case of encoding fail. &lt;/li&gt;&lt;/ul&gt;&lt;a href="http://lh6.ggpht.com/-ed9PdDA8YeE/Tw8VUZHV9zI/AAAAAAAADjg/5_yoaN9BgGQ/s1600-h/MediaAssetsList%25255B1%25255D.png"&gt;&lt;img alt="MediaAssetsList" border="0" height="365" src="http://lh4.ggpht.com/-_vXd1MNWlug/Tw8VVzohoZI/AAAAAAAADjk/znpIijhIDls/MediaAssetsList_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="MediaAssetsList" width="1343" /&gt;&lt;/a&gt;&lt;br /&gt;The list has an event receiver attached in order for deleting the assets from the final destination or temporary folder when the items are deleted from the list.&lt;br /&gt;To achieve the storage flexibility, a custom upload form was developed and hooked to the MediaAssets list. When you click on the “Add new item” link of the picture above, the custom upload form is launched. The form is attached to the base content type definition in the Elements file as this:&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515;"&gt;xml &lt;/span&gt;&lt;span style="color: red;"&gt;version&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;1.0&lt;/span&gt;" &lt;span style="color: red;"&gt;encoding&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;utf-8&lt;/span&gt;"&lt;span style="color: blue;"&gt;?&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Elements &lt;/span&gt;&lt;span style="color: red;"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;http://schemas.microsoft.com/sharepoint/&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style="color: green;"&gt;Parent ContentType: Item (0x01) &lt;/span&gt;&lt;span style="color: blue;"&gt;--&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ContentType &lt;/span&gt;&lt;span style="color: red;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;0x01004e4f21afc14c487892253cb129dd5001&lt;/span&gt;"&lt;br /&gt;               &lt;span style="color: red;"&gt;Name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;MyMediaAsset&lt;/span&gt;" &lt;span style="color: red;"&gt;Group&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;MyContent Types&lt;/span&gt;"&lt;br /&gt;               &lt;span style="color: red;"&gt;Description&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;My Media Asset&lt;/span&gt;" &lt;span style="color: red;"&gt;Inherits&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;TRUE&lt;/span&gt;"&lt;br /&gt;               &lt;span style="color: red;"&gt;Version&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;0&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;FieldRefs&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;    …&lt;/span&gt;&lt;span style="color: blue;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;FieldRefs&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlDocuments&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlDocument &lt;/span&gt;&lt;span style="color: red;"&gt;NamespaceURI&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;FormUrls &lt;/span&gt;&lt;span style="color: red;"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;          &lt;span style="background-color: yellow;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;&lt;span style="color: #a31515;"&gt;New&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;_layouts/MyMedia/Upload.aspx&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;New&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;span style="background-color: yellow;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;FormUrls&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlDocument&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlDocuments&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ContentType&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Elements&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;h5&gt;The Upload Form&lt;/h5&gt;The form was created as an Application Page (Upload.aspx) in the Layouts folder. It contains the browse control to upload the file.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/-cVoQyVVDz4U/Tw8VWj0IjoI/AAAAAAAADi4/a2mQ2JG4Dv4/s1600-h/MediaAssetUploadForm4.png"&gt;&lt;img alt="MediaAssetUploadForm" border="0" height="449" src="http://lh4.ggpht.com/-I9Ya5GrUEtI/Tw8VXs7qgOI/AAAAAAAADjA/kjU27vfkf18/MediaAssetUploadForm_thumb2.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="MediaAssetUploadForm" width="556" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A useful tip here is how to achieve the same look and feel as the Sharepoint OOB forms. The InputFormSeccion, InputFormControl and ButtonSection controls were used for that matter.&lt;br /&gt;&lt;br /&gt;In order to use these controls, you need to register the namespace on the top of the page:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="background-attachment: initial; background-clip: initial; background-color: yellow; background-image: initial; background-origin: initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;@ &lt;/span&gt;&lt;span style="color: maroon;"&gt;Register &lt;/span&gt;&lt;span style="color: red;"&gt;TagPrefix&lt;/span&gt;&lt;span style="color: blue;"&gt;="wssuc" &lt;/span&gt;&lt;span style="color: red;"&gt;TagName&lt;/span&gt;&lt;span style="color: blue;"&gt;="ButtonSection" &lt;/span&gt;&lt;span style="color: red;"&gt;Src&lt;/span&gt;&lt;span style="color: blue;"&gt;="/_controltemplates/ButtonSection.ascx" &lt;/span&gt;&lt;span style="background-attachment: initial; background-clip: initial; background-color: yellow; background-image: initial; background-origin: initial;"&gt;%&amp;gt;&lt;br /&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;@ &lt;/span&gt;&lt;span style="color: maroon;"&gt;Register &lt;/span&gt;&lt;span style="color: red;"&gt;TagPrefix&lt;/span&gt;&lt;span style="color: blue;"&gt;="wssuc" &lt;/span&gt;&lt;span style="color: red;"&gt;TagName&lt;/span&gt;&lt;span style="color: blue;"&gt;="InputFormSection" &lt;/span&gt;&lt;span style="color: red;"&gt;Src&lt;/span&gt;&lt;span style="color: blue;"&gt;="/_controltemplates/InputFormSection.ascx" &lt;/span&gt;&lt;span style="background-attachment: initial; background-clip: initial; background-color: yellow; background-image: initial; background-origin: initial;"&gt;%&amp;gt;&lt;br /&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;@ &lt;/span&gt;&lt;span style="color: maroon;"&gt;Register &lt;/span&gt;&lt;span style="color: red;"&gt;TagPrefix&lt;/span&gt;&lt;span style="color: blue;"&gt;="wssuc" &lt;/span&gt;&lt;span style="color: red;"&gt;TagName&lt;/span&gt;&lt;span style="color: blue;"&gt;="InputFormControl" &lt;/span&gt;&lt;span style="color: red;"&gt;Src&lt;/span&gt;&lt;span style="color: blue;"&gt;="/_controltemplates/InputFormControl.ascx" &lt;/span&gt;&lt;span style="background-attachment: initial; background-clip: initial; background-color: yellow; background-image: initial; background-origin: initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;And then include them in the page like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;wssuc&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: maroon;"&gt;&lt;strong&gt;&lt;span style="background-color: yellow;"&gt;InputFormSection&lt;/span&gt;&lt;/strong&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;="InputFormSection1" &lt;/span&gt;&lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server"&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: red;"&gt;Title&lt;/span&gt;&lt;span style="color: blue;"&gt;="Upload Document" &lt;/span&gt;&lt;span style="color: red;"&gt;Description&lt;/span&gt;&lt;span style="color: blue;"&gt;="Browse to the media asset you intend to upload." &amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;template_inputformcontrols&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;wssuc&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: maroon;"&gt;&lt;strong&gt;&lt;span style="background-color: yellow;"&gt;InputFormControl&lt;/span&gt;&lt;/strong&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server" &lt;/span&gt;&lt;span style="color: red;"&gt;LabelText&lt;/span&gt;&lt;span style="color: blue;"&gt;="" &amp;gt;&lt;br /&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;Template_Control&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;                   &lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;div &lt;/span&gt;&lt;span style="color: red;"&gt;class&lt;/span&gt;&lt;span style="color: blue;"&gt;="ms-authoringcontrols"&amp;gt;&lt;br /&gt;          &lt;/span&gt;Name: &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;br &lt;/span&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;input &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="FileToUpload" &lt;/span&gt;&lt;span style="color: red;"&gt;class&lt;/span&gt;&lt;span style="color: blue;"&gt;="ms-fileinput" &lt;/span&gt;&lt;span style="color: red;"&gt;size&lt;/span&gt;&lt;span style="color: blue;"&gt;="35" &lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="file" &lt;/span&gt;&lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server"&amp;gt;    &lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: maroon;"&gt;RequiredFieldValidator &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="RequiredFieldValidator" &lt;/span&gt;&lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server" &lt;/span&gt;&lt;span style="color: red;"&gt;ErrorMessage&lt;/span&gt;&lt;span style="color: blue;"&gt;="You must specify a value for the required field." &lt;/span&gt;&lt;span style="color: red;"&gt;ControlToValidate&lt;/span&gt;&lt;span style="color: blue;"&gt;="FileToUpload"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: maroon;"&gt;RequiredFieldValidator&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;br &lt;/span&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: maroon;"&gt;RegularExpressionValidator &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="FileExtensionValidator" &lt;/span&gt;&lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server" &lt;/span&gt;&lt;span style="color: red;"&gt;ErrorMessage&lt;/span&gt;&lt;span style="color: blue;"&gt;="Invalid file name." &lt;/span&gt;&lt;span style="color: red;"&gt;ControlToValidate&lt;/span&gt;&lt;span style="color: blue;"&gt;="FileToUpload"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: maroon;"&gt;RegularExpressionValidator&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;          &lt;/span&gt;&lt;span style="color: blue;"&gt;…&lt;/span&gt;&lt;span style="color: blue;"&gt;                                                                         &lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;      &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;Template_Control&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;wssuc&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: maroon;"&gt;InputFormControl&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;template_inputformcontrols&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;wssuc&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: maroon;"&gt;InputFormSection&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;You can read more about how to use these controls &lt;a href="http://karinebosch.wordpress.com/sharepoint-controls/inputformsectionascx-control/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So, what happens in the code behind?&lt;br /&gt;&lt;br /&gt;On the OK button submit handler, the file to upload is processed. The logic is different depending on the asset type. Images are copied to the final destination by using the Storage Manager. A thumbnail is also generated and uploaded for them. Duration is calculated for Audio and Video files (Microsoft.WindowsAPICodePack API is used for that). Audio files are also copied to the final destination. Videos instead are leaved in a temporary storage (a network shared folder), because they need to be processed later by the timer job.&lt;br /&gt;&lt;br /&gt;In all three cases, a list item is created with the asset metadata, and inserted into the MediaAssets list. Then the user is redirected to the list item Edit form, so he can complete filling the rest of the metadata.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/-CBRyGaoHb3E/Tw8VYCVwO1I/AAAAAAAADjI/7RxydLw6RPc/s1600-h/MediaAssetsEditForm3.png"&gt;&lt;img alt="MediaAssetsEditForm" border="0" height="402" src="http://lh6.ggpht.com/-dRlE3scNQHM/Tw8VZMTiW-I/AAAAAAAADjQ/ylpRmhGVtZY/MediaAssetsEditForm_thumb1.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="MediaAssetsEditForm" width="623" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Since the upload process may take a long time, all this happens in the context of an SPLongOperation. This is a Sharepoint class provided to display the “Processing…” dialog with the rotating gear image in it.&lt;br /&gt;&lt;br /&gt;Here is part of the code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;protected void &lt;/span&gt;btnOk_Click(&lt;span style="color: blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af;"&gt;EventArgs &lt;/span&gt;e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue;"&gt;if &lt;/span&gt;(FileToUpload.PostedFile == &lt;span style="color: blue;"&gt;null &lt;/span&gt;|| &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.IsNullOrEmpty(FileToUpload.PostedFile.FileName))&lt;br /&gt;        &lt;span style="color: blue;"&gt;return&lt;/span&gt;;     &lt;span style="color: green;"&gt;//FileToUpload is the HtmlInputFile control&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;var &lt;/span&gt;originFileInfo = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;FileInfo&lt;/span&gt;(FileToUpload.PostedFile.FileName);&lt;br /&gt;    &lt;span style="color: #2b91af;"&gt;SPWeb &lt;/span&gt;web = &lt;span style="color: #2b91af;"&gt;SPContext&lt;/span&gt;.Current.Web;&lt;br /&gt;    &lt;span style="color: blue;"&gt;try&lt;br /&gt;    &lt;/span&gt;{&lt;br /&gt;        &lt;span style="color: green;"&gt;//create a MediaAsset object to save all asset metadata&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;MediaAsset &lt;/span&gt;asset = &lt;span style="color: #2b91af;"&gt;MediaAsset&lt;/span&gt;.FromFile(originFileInfo, web.Url, mediaConfig);&lt;br /&gt;        &lt;span style="color: green;"&gt;//start long operation to show the user the "Processing..." message&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;SPLongOperation &lt;/span&gt;longOperation = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;SPLongOperation&lt;/span&gt;(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.Page))&lt;br /&gt;        {&lt;br /&gt;            longOperation.Begin();&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: blue;"&gt;string &lt;/span&gt;newFileUniqueName = &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Concat(&lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt;.NewGuid().ToString(), originFileInfo.Extension);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #2b91af;"&gt;SPSecurity&lt;/span&gt;.RunWithElevatedPrivileges(&lt;span style="color: blue;"&gt;delegate&lt;/span&gt;()&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: green;"&gt;//save to file system. Need to elevate privileges for that&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: blue;"&gt;var &lt;/span&gt;tempFileInfo = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;FileInfo&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;Path&lt;/span&gt;.Combine(mediaConfig.TempLocationFolder, newFileUniqueName));&lt;br /&gt;                FileToUpload.PostedFile.SaveAs(tempFileInfo.FullName);&lt;br /&gt;&lt;br /&gt;                asset.TempLocation = tempFileInfo.FullName;&lt;br /&gt;                asset.Duration = &lt;span style="color: #2b91af;"&gt;MediaLengthCalculator&lt;/span&gt;.GetMediaLength(tempFileInfo);&lt;br /&gt;                ...&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: blue;"&gt;var &lt;/span&gt;list = web.Lists[mediaConfig.MediaAssetsListName];&lt;br /&gt;            &lt;span style="color: blue;"&gt;int &lt;/span&gt;id;&lt;br /&gt;            &lt;span style="color: blue;"&gt;string &lt;/span&gt;contentTypeId;&lt;br /&gt;            &lt;span style="color: green;"&gt;//insert new item in the MediaAssets list&lt;br /&gt;            &lt;/span&gt;mediaRepository.Insert(list, asset, &lt;span style="color: blue;"&gt;out &lt;/span&gt;id, &lt;span style="color: blue;"&gt;out &lt;/span&gt;contentTypeId);&lt;br /&gt;            &lt;span style="color: green;"&gt;//build url of Edit Form to redirect &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: blue;"&gt;string &lt;/span&gt;url = &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515;"&gt;"{0}?ID={1}&amp;amp;ContentTypeId={2}"&lt;/span&gt;, list.DefaultEditFormUrl, id, contentTypeId);&lt;br /&gt;            &lt;span style="color: green;"&gt;//long operation ends, redirecting to the Edit Form of the new list item&lt;br /&gt;            &lt;/span&gt;longOperation.End(url);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: blue;"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;ThreadAbortException&lt;/span&gt;) { &lt;span style="color: green;"&gt;/* Thrown when redirected */&lt;/span&gt;}&lt;br /&gt;    &lt;span style="color: blue;"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;Exception &lt;/span&gt;ex)&lt;br /&gt;    {&lt;br /&gt;        logger.LogToOperations(ex, &lt;span style="color: #2b91af;"&gt;Categories&lt;/span&gt;.Media, &lt;span style="color: #2b91af;"&gt;EventSeverity&lt;/span&gt;.Error,&lt;br /&gt;            &lt;span style="color: #a31515;"&gt;"Error uploading file to MediaAssets list. FileName: '{0}'."&lt;/span&gt;, originFileInfo.Name);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #2b91af;"&gt;SPUtility&lt;/span&gt;.TransferToErrorPage(ex.Message);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ok, now let’s see how the asynchronous processing part works.&lt;br /&gt;&lt;h4&gt;&lt;u&gt;2. Media Processing Backend Process&lt;/u&gt;&lt;/h4&gt;&lt;br /&gt;The backend process consists of a Sharepoint Timer Job that orchestrates the video processing and a console application that performs the actual encoding and generate the images. The console application is invoked by the timer job.&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;Encoder Console Application&lt;/h5&gt;The tool chosen for encoding videos was &lt;a href="http://social.expression.microsoft.com/Forums/en/encoder/thread/3eabf903-b49f-4f92-b508-f28a795d6c90"&gt;Microsoft Expression Encoder 4&lt;/a&gt;. We used the Pro version (paid) which includes support for H.264 (this means can encode videos to mp4 format as required by our client).&lt;br /&gt;&lt;br /&gt;The encoder comes with an SDK, so you can programmatically encode your videos. The thing is that this API depends upon .Net Framework 4.0, and it is also 32-bit only. This is incompatible with a Sharepoint process (either web or timer job), since Sharepoint relies upon .Net 3.5 and runs in 64 bits. Hence the need to build a separate process outside of the Sharepoint Timer Job. The console application was a simple solution, and it could be configured to target .Net Framework 4.0 and x86 Platform.&lt;br /&gt;&lt;br /&gt;This application expects four input parameters: the path to the original video, the desired path for the thumbnail image to generate, the desired path of the poster image to generate and the desired path of the encoded video to generate.&lt;br /&gt;&lt;br /&gt;The Encoder SDK provides full flexibility for setting the encoding parameters (like format, size, bitrate, etc). It also provides a set of presets, that let’s you implement the encoding very easily. For example, here is the code for encoding using the H264VimeoSD Preset:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public void &lt;/span&gt;EncodeVideo(&lt;span style="color: #2b91af;"&gt;FileInfo &lt;/span&gt;inputFile, &lt;span style="color: #2b91af;"&gt;FileInfo &lt;/span&gt;outputFile)&lt;br /&gt;{&lt;br /&gt;    Microsoft.Expression.Encoder.&lt;span style="color: #2b91af;"&gt;MediaItem &lt;/span&gt;mediaItem = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;MediaItem&lt;/span&gt;(inputFile.FullName);&lt;br /&gt;    &lt;span style="color: blue;"&gt;int &lt;/span&gt;bitrate = GetBitrate(mediaItem);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue;"&gt;using &lt;/span&gt;(Microsoft.Expression.Encoder.&lt;span style="color: #2b91af;"&gt;Job &lt;/span&gt;job = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;Job&lt;/span&gt;())&lt;br /&gt;    {&lt;br /&gt;        job.OutputDirectory = outputFile.Directory.FullName;&lt;br /&gt;        job.CreateSubfolder = &lt;span style="color: blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;        job.MediaItems.Add(mediaItem);&lt;br /&gt;        &lt;span style="color: green;"&gt;//H264VimeoSD preset settings: Output Format: MP4. Container: MP4. Video Codec: H.264 - Main. &lt;br /&gt;        //Video size: 640, 480. Video Bitrate: 2500 Kbps. Video Encoding: CBR SinglePass. &lt;br /&gt;        //Audio Codec: AAC. Audio Channels: Stereo. Audio Bitrate: 128 Kbps. Audio Encoding: CBR Single Pass&lt;br /&gt;        &lt;/span&gt;job.ApplyPreset(Microsoft.Expression.Encoder.&lt;span style="color: #2b91af;"&gt;Presets&lt;/span&gt;.H264VimeoSD);&lt;br /&gt;        job.Encode();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;And here is the code for generating the thumbnail or poster images:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public void &lt;/span&gt;GenerateVideoImage(&lt;span style="color: #2b91af;"&gt;FileInfo &lt;/span&gt;mediaFile, &lt;span style="color: blue;"&gt;string &lt;/span&gt;imageFilePath, &lt;span style="color: blue;"&gt;int &lt;/span&gt;width, &lt;span style="color: blue;"&gt;int &lt;/span&gt;height)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue;"&gt;var &lt;/span&gt;video = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;MediaItem&lt;/span&gt;(mediaFile.FullName);&lt;br /&gt;    &lt;span style="color: blue;"&gt;using &lt;/span&gt;(&lt;span style="color: blue;"&gt;var &lt;/span&gt;bitmap = video.MainMediaFile.GetThumbnail(&lt;br /&gt;        &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;TimeSpan&lt;/span&gt;(0, 0, 5),&lt;br /&gt;        &lt;span style="color: blue;"&gt;new &lt;/span&gt;System.Drawing.&lt;span style="color: #2b91af;"&gt;Size&lt;/span&gt;(width, height)))&lt;br /&gt;    {&lt;br /&gt;        bitmap.Save(imageFilePath, &lt;span style="color: #2b91af;"&gt;ImageFormat&lt;/span&gt;.Jpeg);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;h5&gt;Media Processing Timer Job&lt;/h5&gt;Sharepoint supports asynchronous processing of data through Timer Jobs. These jobs run within the context of a windows service, and are easily managed and deployed using the same tools as any other Sharepoint solution.&lt;br /&gt;&lt;br /&gt;As the requirement was to run the job only in one of the application servers, it inherits from &lt;a href="http://msdn.microsoft.com/en-us/library/ee543400.aspx"&gt;SPServerJobDefinition&lt;/a&gt;. Here is the Timer Job code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;MediaProcessingTimerJob&lt;/span&gt;: &lt;span style="color: #2b91af;"&gt;SPServerJobDefinition &lt;/span&gt;{ &lt;br /&gt;    &lt;span style="color: blue;"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;Logger &lt;/span&gt;logger = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;Logger&lt;/span&gt;(); &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue;"&gt;public &lt;/span&gt;MediaProcessingTimerJob() : &lt;span style="color: blue;"&gt;base&lt;/span&gt;() &lt;br /&gt;    { &lt;br /&gt;    } &lt;br /&gt;        &lt;br /&gt;    &lt;span style="color: blue;"&gt;public &lt;/span&gt;MediaProcessingTimerJob(&lt;span style="color: blue;"&gt;string &lt;/span&gt;name,&lt;span style="color: #2b91af;"&gt;SPServer &lt;/span&gt;server):&lt;span style="color: blue;"&gt;base&lt;/span&gt;(name,server) &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Title = &lt;span style="color: #a31515;"&gt;"MediaProcessingTimerJob"&lt;/span&gt;; &lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue;"&gt;public override void &lt;/span&gt;Execute(&lt;span style="color: #2b91af;"&gt;SPJobState &lt;/span&gt;jobState) &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: blue;"&gt;string &lt;/span&gt;webUrl = &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Empty; &lt;br /&gt;        &lt;span style="color: blue;"&gt;try &lt;br /&gt;       &lt;/span&gt;{ &lt;br /&gt;            webUrl = &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Properties[&lt;span style="color: #a31515;"&gt;"webUrl"&lt;/span&gt;].ToString(); &lt;br /&gt;            &lt;span style="color: blue;"&gt;var &lt;/span&gt;mediaProcessor = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;MediaProcessor&lt;/span&gt;(webUrl, &lt;span style="color: #2b91af;"&gt;MediaConfig&lt;/span&gt;.FromConfigRepository(webUrl)); &lt;br /&gt;            mediaProcessor.ProcessMedia(); &lt;br /&gt;        } &lt;br /&gt;        &lt;span style="color: blue;"&gt;catch&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;Exception &lt;/span&gt;ex) &lt;br /&gt;        { &lt;br /&gt;            logger.LogToOperations(ex,&lt;span style="color: #2b91af;"&gt;TRSCategories&lt;/span&gt;.Media, &lt;span style="color: #2b91af;"&gt;EventSeverity&lt;/span&gt;.Error, &lt;span style="color: #a31515;"&gt;"Error executing MediaProcessingTimerJob in web '{0}'"&lt;/span&gt;, webUrl); &lt;br /&gt;        } &lt;br /&gt;    } &lt;br /&gt;} &lt;/pre&gt;&lt;br /&gt;During the deployment process, the MediaProcessingTimerJob is installed on the required server. The URL of the website for processing the assets are passed thru the job properties.&lt;br /&gt;&lt;br /&gt;Here is part of the code of the helper tool that installs the job and sets it to run every 15 minutes:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;private static void &lt;/span&gt;CreateMediaJob(&lt;span style="color: blue;"&gt;string &lt;/span&gt;webUrl,&lt;span style="color: #2b91af;"&gt;SPServer &lt;/span&gt;server)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue;"&gt;var &lt;/span&gt;job = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;MediaProcessingTimerJob&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"my-job-media-processing"&lt;/span&gt;, server);&lt;br /&gt;            &lt;br /&gt;    job.Properties.Add(&lt;span style="color: #a31515;"&gt;"webUrl"&lt;/span&gt;, webUrl);&lt;br /&gt;            &lt;br /&gt;    &lt;span style="color: blue;"&gt;var &lt;/span&gt;schedule = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;SPMinuteSchedule&lt;/span&gt;();&lt;br /&gt;    schedule.BeginSecond = 0;&lt;br /&gt;    schedule.EndSecond = 59;&lt;br /&gt;    schedule.Interval = 15;&lt;br /&gt;    job.Schedule = schedule;&lt;br /&gt;    job.Update();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The logic of the timer job resides in the MediaProcessor::ProcessMedia method. It essentially queries the Media Assets List for assets in the “Pending” status and for each of these items it invokes the Encoder process and then uploads the resulting mp4 video and the generated thumbnail and poster images to the final destination. Finally it notifies the user of the result by email.&lt;br /&gt;&lt;br /&gt;This is the code that the job uses to call the console application. Since the job tells the console application the output parameters (the path to the images and encoded video files), it doesn’t need to read any output from the console application. It must only read the standard error in case the console application fails.&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;private void &lt;/span&gt;ExecuteMediaProcess(&lt;span style="color: blue;"&gt;string &lt;/span&gt;inVideoPath,&lt;span style="color: blue;"&gt;string &lt;/span&gt;outThumbnailPath, &lt;span style="color: blue;"&gt;string &lt;/span&gt;outPosterPath,&lt;span style="color: blue;"&gt;string &lt;/span&gt;outVideoPath)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue;"&gt;string &lt;/span&gt;args = &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515;"&gt;"\"{0}\" \"{1}\" \"{2}\" \"{3}\""&lt;/span&gt;, inVideoPath, outThumbnailPath, outPosterPath, outVideoPath);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #2b91af;"&gt;ProcessStartInfo &lt;/span&gt;startInfo = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ProcessStartInfo&lt;/span&gt;(config.EncoderExePath);&lt;br /&gt;    startInfo.Arguments = args;&lt;br /&gt;    startInfo.CreateNoWindow = &lt;span style="color: blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;    startInfo.UseShellExecute = &lt;span style="color: blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;    startInfo.RedirectStandardError = &lt;span style="color: blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;    startInfo.RedirectStandardOutput = &lt;span style="color: blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #2b91af;"&gt;Process &lt;/span&gt;process = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;Process&lt;/span&gt;();&lt;br /&gt;    process.StartInfo = startInfo;&lt;br /&gt;    process.Start();&lt;br /&gt;    &lt;span style="color: blue;"&gt;string &lt;/span&gt;error = process.StandardError.ReadToEnd();&lt;br /&gt;    process.WaitForExit(MaxWaitingProcessMillisecs);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue;"&gt;if &lt;/span&gt;(process.ExitCode != 0)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: green;"&gt;//the application failed, get error from message from standard error&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;MediaProcessingException&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515;"&gt;"Video encoder process returned with exit code '{0}'. Error was: '{1}'"&lt;/span&gt;,&lt;br /&gt;            process.ExitCode, error));&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;&lt;u&gt;3. Storage Manager&lt;/u&gt;&lt;/h4&gt;The Storage Manager is the piece of code used by both the upload media form and the backend process. It is just a file manager used for abstracting from the actual destination of the files, which is configurable. As I said, we started supporting saving assets to File System, to a Sharepoint library or to an FTP server, but this can be further extended to support other places, like some storage on the Cloud.&lt;br /&gt;&lt;br /&gt;The need for a flexibility in the location to store the files may come from bandwidth or space limitations, for a need to share assets with other applications or a need to manage a centralized file store.&lt;br /&gt;&lt;br /&gt;Anyway, the interface is very simple:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IAssetStorageManager&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color: blue;"&gt;void &lt;/span&gt;Delete(&lt;span style="color: blue;"&gt;string &lt;/span&gt;fileUrl);&lt;br /&gt;    &lt;span style="color: blue;"&gt;string &lt;/span&gt;Save(System.IO.&lt;span style="color: #2b91af;"&gt;FileInfo &lt;/span&gt;file);&lt;br /&gt;    &lt;span style="color: blue;"&gt;string &lt;/span&gt;Save(&lt;span style="color: blue;"&gt;string &lt;/span&gt;fileName, System.IO.&lt;span style="color: #2b91af;"&gt;Stream &lt;/span&gt;fileStream);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;There is a factory that will give you the particular storage manager framework depending on configuration (all configuration is saved in a Sharepoint list, and the &lt;a href="http://spconfigstore.codeplex.com/"&gt;Sharepoint Config Store&lt;/a&gt; is used for retrieving it). Here is part of the factory code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;AssetStorageFactory&lt;/span&gt;{    …&lt;br /&gt;    &lt;span style="color: blue;"&gt;static public &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IAssetStorageManager &lt;/span&gt;GetStorageManager(&lt;span style="color: blue;"&gt;string &lt;/span&gt;configCategory,&lt;span style="color: blue;"&gt;string &lt;/span&gt;webUrl)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue;"&gt;var &lt;/span&gt;configHelper = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ConfigHelper&lt;/span&gt;(webUrl);&lt;br /&gt;        &lt;span style="color: blue;"&gt;string &lt;/span&gt;storageMethod = configHelper.GetValue(configCategory, StorageMethodConfigKey);&lt;br /&gt;        &lt;span style="color: blue;"&gt;if &lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"SPLibrary"&lt;/span&gt;.Equals(storageMethod, &lt;span style="color: #2b91af;"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase))&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue;"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;SPLibraryAssetStorageManager&lt;/span&gt;(webUrl, mediaLibraryName);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: blue;"&gt;else if &lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"FileSystem"&lt;/span&gt;.Equals(storageMethod, &lt;span style="color: #2b91af;"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase))&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue;"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;FileSystemAssetStorageManager&lt;/span&gt;(storageFolderPath,storageBaseAddress);&lt;br /&gt;        }   &lt;br /&gt;        &lt;span style="color: blue;"&gt;else if &lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"FTP"&lt;/span&gt;.Equals(storageMethod, &lt;span style="color: #2b91af;"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase))&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue;"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;FTPAssetStorageManager&lt;/span&gt;(ftpServerUrl,ftpServerPullAdress,ftpServerUsername,ftpServerPassword);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: blue;"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515;"&gt;"Incorrect configuration Value '{0}' in ConfigStore for category '{1}' and key '{2}'. Supported options are: '{3}'"&lt;/span&gt;,&lt;br /&gt;            storageMethod, configCategory, StorageMethodConfigKey, &lt;span style="color: #a31515;"&gt;"FileSystem|FTP|SPLibrary"&lt;/span&gt;));&lt;br /&gt;    }       &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The implementation for a particular flavor is simple. For example, this is how the FTPAssetStorageManager saves a file stream:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public string &lt;/span&gt;Save(&lt;span style="color: blue;"&gt;string &lt;/span&gt;fileName, System.IO.&lt;span style="color: #2b91af;"&gt;Stream &lt;/span&gt;fileStream)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue;"&gt;string &lt;/span&gt;fileUrl = ftpServerUrl + fileName;&lt;br /&gt;    &lt;span style="color: #2b91af;"&gt;FtpWebRequest &lt;/span&gt;request = (&lt;span style="color: #2b91af;"&gt;FtpWebRequest&lt;/span&gt;)&lt;span style="color: #2b91af;"&gt;WebRequest&lt;/span&gt;.Create(fileUrl);&lt;br /&gt;    request.Method = &lt;span style="color: #2b91af;"&gt;WebRequestMethods&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;Ftp&lt;/span&gt;.UploadFile;&lt;br /&gt;    request.Credentials = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;NetworkCredential&lt;/span&gt;(username, password);&lt;br /&gt;    &lt;span style="color: blue;"&gt;using &lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;Stream &lt;/span&gt;ftpStream = request.GetRequestStream())&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #2b91af;"&gt;FileUtils&lt;/span&gt;.CopyStream(fileStream, ftpStream);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: blue;"&gt;return &lt;/span&gt;pullBaseAddress + fileName;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;And this is how the storage manager is invoked from the Upload form or the Timer Job:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: green;"&gt;//save to final location&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IAssetStorageManager &lt;/span&gt;storage = &lt;span style="color: #2b91af;"&gt;AssetStorageFactory&lt;/span&gt;.GetStorageManager(&lt;span style="color: #a31515;"&gt;"Media"&lt;/span&gt;, web.Url);&lt;br /&gt;asset.Location = storage.Save(newFileUniqueName, fileInputStream);&lt;/pre&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;Having talked about the most important parts of the Media Processing Component for Sharepoint, I think I’m done here. The code is too much to show everything in a post, but I’ve chosen the most important parts. I might dig deeper in some other post. I will probably write about how to display videos in a web page, too.&lt;br /&gt;&lt;br /&gt;The interesting part is that even if this whole component doesn’t apply to another project, maybe some of its pieces can be reused, like the video encoding thing, or the custom upload form and storage manager to save files outside Sharepoint. So I hope it results useful to someone else!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-4097080241407195991?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/4097080241407195991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=4097080241407195991&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4097080241407195991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4097080241407195991'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2012/01/media-processing-component-for.html' title='Media Processing Component for Sharepoint'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-q8zy4wchepQ/Tw8VS2h9VTI/AAAAAAAADjc/qHUjlvHC5Ek/s72-c/MediaProcessing_thumb%25255B3%25255D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-8460885013113994336</id><published>2011-12-15T09:42:00.001-03:00</published><updated>2011-12-15T09:47:47.603-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><title type='text'>Sharepoint Upload File Error: ‘The remote server returned an error: (409) Conflict’</title><content type='html'>I’ve been using the following code to upload a file to a Sharepoint document library using the Client Object Model:&lt;br /&gt;&lt;div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;"&gt;&lt;div style="background: #000080; color: white; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;"&gt;Code Snippet&lt;/div&gt;&lt;div style="background: #ddd; max-height: 300px; overflow: auto;"&gt;&lt;ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"&gt;&lt;li&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Save(&lt;span style="color: blue;"&gt;string&lt;/span&gt; fileName, Stream fileStream)&lt;/li&gt;&lt;li style="background: #f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; destinationUrl = String.Concat(serverRelativeLibraryUrl, &lt;span style="color: #a31515;"&gt;"/"&lt;/span&gt;, fileName);&lt;/li&gt;&lt;li style="background: #f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ClientContext clientContext = &lt;span style="color: blue;"&gt;new&lt;/span&gt; ClientContext(webUrl);&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/li&gt;&lt;li style="background: #f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, destinationUrl, fileStream, &lt;span style="color: blue;"&gt;true&lt;/span&gt;);&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/li&gt;&lt;li style="background: #f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt; destinationUrl;&lt;/li&gt;&lt;li style="background: #f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;where &lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;serverRelativeLibraryUrl = String.Concat(webRelativeUrl, libraryName);   &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But I kept getting the 409 Conflict Error:&lt;br /&gt;ExceptionType: 'WebException'&amp;nbsp; ExceptionMessage: '&lt;b&gt;The remote server returned an error: (409) Conflict&lt;/b&gt;.'&amp;nbsp;&amp;nbsp; StackTrace: '&amp;nbsp; &lt;br /&gt;at System.Net.HttpWebRequest.GetResponse()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;at Microsoft.SharePoint.Client.SPWebRequestExecutor.Execute()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;at Microsoft.SharePoint.Client.File.SaveBinary(ClientContext context, String serverRelativeUrl, Stream stream, String etag, Boolean overwriteIfExists, SaveBinaryCheckMode checkMode)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;at Microsoft.SharePoint.Client.File.SaveBinaryDirect(ClientContext context, String serverRelativeUrl, Stream stream, Boolean overwriteIfExists)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;After struggling for a while, I figured out that the problem was the library name. It contained a dash on it, like “My-LibraryName”. When I renamed it without the dash it started working. &lt;br /&gt;&lt;br /&gt;The error in the code is how I built the URL. I was using the library name to build the library URL, but it seems that Sharepoint doesn’t like some characters in the URL, so when you create a library called “My-LibraryName”, the URL is actually &lt;a href="http://%3Cserver%3E/MyLibraryName"&gt;http://&amp;lt;server&amp;gt;/MyLibraryName&lt;/a&gt;, without the dash. &lt;br /&gt;&lt;br /&gt;&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:67c82d94-41ce-45d5-80c3-5115aac94f6b" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Sharepoint" rel="tag"&gt;Sharepoint&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-8460885013113994336?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/8460885013113994336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=8460885013113994336&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/8460885013113994336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/8460885013113994336'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2011/12/sharepoint-upload-file-error-remote.html' title='Sharepoint Upload File Error: ‘The remote server returned an error: (409) Conflict’'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-803253196825244321</id><published>2011-09-21T00:43:00.001-03:00</published><updated>2011-09-21T12:42:30.505-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeCamp'/><category scheme='http://www.blogger.com/atom/ns#' term='Jquery'/><title type='text'>Sharepoint @ Buenos Aires Codecamp 2011</title><content type='html'>BA Codecamp 2011 is coming soon and &lt;a href="http://www.tellago.com/"&gt;Tellago&lt;/a&gt; is going to be &lt;a href="http://www.codecamp.com.ar/sponsors#platino"&gt;part of it&lt;/a&gt;! More than 10 architects from our team will be presenting the most innovative technology sessions on next October 15. I’m very happy to be speaking at this event! Along with my colleague Mariano Escurra, we will be presenting Best Practices using Javascript and JQuery in Sharepoint 2010. Bellow is the abstract. Register!! &lt;br /&gt;&lt;p&gt;&lt;b&gt;&lt;i&gt;Mejores prácticas utilizando Javascript y JQuery en SharePoint 2010        &lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;i&gt;El uso de Javascript es una parte importante en la construcción de cualquier sitio web interactivo, siendo JQuery una de las bibliotecas Javascript más utilizadas. Al crear este tipo de sitios sobre SharePoint 2010, los desarrolladores pueden combinar el uso esta biblioteca con el modelo de objetos cliente Javascript (ECMAScript) mejorando notablemente la experiencia del usuario final.      &lt;br /&gt;Durante esta charla abordaremos los aspectos más importantes del modelo de objetos cliente ECMAScript de SharePoint 2010 y su integración con JQuery siguiendo las mejores prácticas. &lt;/i&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032493728&amp;amp;Culture=es-AR" target="_blank"&gt;&lt;img alt="Banner CodeCamp 587x293" src="http://www.codecamp.com.ar/themes/codecamp/content/media/misc/ban_ar-uru_codecamp_587x293.jpg" style="height: 293px; width: 587px;" /&gt; &lt;/a&gt;       &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-803253196825244321?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/803253196825244321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=803253196825244321&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/803253196825244321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/803253196825244321'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2011/09/sharepoint-buenos-aires-codecamp-2011.html' title='Sharepoint @ Buenos Aires Codecamp 2011'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-5333171009540756631</id><published>2011-06-17T10:35:00.001-03:00</published><updated>2011-06-17T10:35:38.416-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><title type='text'>Fixing Sharepoint’s “Cannot connect to the configuration database” error</title><content type='html'>&lt;p&gt;I have Sharepoint Server 2010 installed in my development environment. It happened a couple of times that the computer hangs and the Sharepoint Configuration dabatase remains in a corrupted state. When I try to access the Sharepoint local site from the browser it gives the following error:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="510"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="508"&gt;         &lt;h4&gt;&lt;i&gt;Cannot connect to the configuration database.&lt;/i&gt;&lt;/h4&gt;         &lt;b&gt;Description: &lt;/b&gt;An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.           &lt;br /&gt;&lt;b&gt;Exception Details: &lt;/b&gt;Microsoft.SharePoint.WebPartPages.WebPartPageUserException: Cannot connect to the configuration database.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;So, how did I fix it?&lt;/p&gt;  &lt;p&gt;I first used this &lt;a href="http://archive.msdn.microsoft.com/addselftosqlsysadmin/Release/ProjectReleases.aspx?ReleaseId=3954"&gt;addselftosqlsysadmin.cmd&lt;/a&gt; script to add my account to the SQLServer &lt;strong&gt;sysadmin&lt;/strong&gt; group.&lt;/p&gt;  &lt;p&gt;Then performed the following commands from SQL Server Management Studio:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;select state_desc from master.sys.databases where name = 'SharePoint_Config_5ffca14b-db6f-4b30-9dd8-8317ee0f4f45'&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The result was: &lt;strong&gt;SUSPECT&lt;/strong&gt;, confirming we had a problem.&lt;/p&gt;  &lt;p&gt;Then run:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ALTER DATABASE [SharePoint_Config_5ffca14b-db6f-4b30-9dd8-8317ee0f4f45]&amp;#160; SET EMERGENCY;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;GO&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ALTER DATABASE [SharePoint_Config_5ffca14b-db6f-4b30-9dd8-8317ee0f4f45]&amp;#160; SET SINGLE_USER;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;GO&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;DBCC CHECKDB ([SharePoint_Config_5ffca14b-db6f-4b30-9dd8-8317ee0f4f45] , REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS, ALL_ERRORMSGS;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;GO&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ALTER DATABASE [SharePoint_Config_5ffca14b-db6f-4b30-9dd8-8317ee0f4f45]&amp;#160; SET MULTI_USER;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;GO&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;That’s it! I run the &lt;strong&gt;state_desc&lt;/strong&gt; command again and this time it says: &lt;strong&gt;ONLINE&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Solved!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-5333171009540756631?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/5333171009540756631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=5333171009540756631&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/5333171009540756631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/5333171009540756631'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2011/06/fixing-sharepoints-cannot-connect-to.html' title='Fixing Sharepoint’s “Cannot connect to the configuration database” error'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-5718724358217011647</id><published>2011-04-01T10:25:00.000-03:00</published><updated>2011-04-01T10:29:59.364-03:00</updated><title type='text'>Azure Bootcamp @MS Argentina</title><content type='html'>I participated yesterday in the Azure Bootcamp that took place at  Microsoft Argentina. Along with Vanesa Guccione, my colleague at Lagash,  we talked about advanced roles. The contents of the presentation  included the new features of the platform, such as full IIS mode,  startup tasks, remote desktop plugin and local storage. We also talked  about input and internal endpoints and inter-role communication, showing  some demo code as well. You can download the material from &lt;a href="http://weblogs.asp.net/blogs/spano/AzureBootcamp-AdvancedRoles.zip" title="here"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-5718724358217011647?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/5718724358217011647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=5718724358217011647&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/5718724358217011647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/5718724358217011647'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2011/04/azure-bootcamp-ms-argentina.html' title='Azure Bootcamp @MS Argentina'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-2719979037721723857</id><published>2008-10-07T11:08:00.001-03:00</published><updated>2008-10-07T11:20:17.505-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>How to find Visual Studio command bars</title><content type='html'>&lt;p&gt;&lt;p&gt;When developing a Visual Studio Addin it is a common task to add custom commands to existing menus and toolbars. It is a common problem too, not to find the proper command bar (we have to traverse all command bars to see its names, the names are not unique, etc). In these two posts: &lt;a href="http://blogs.msdn.com/dr._ex/archive/2007/04/17/using-ivsproffercommands-to-retrieve-a-visual-studio-commandbar.aspx"&gt;Using IVsProfferCommands to retrieve a Visual Studio CommandBar&lt;/a&gt; and  &lt;a href="http://blogs.msdn.com/dr._ex/archive/2007/04/17/using-enablevsiplogging-to-identify-menus-and-commands-with-vs-2005-sp1.aspx"&gt;Using EnableVSIPLogging to identify menus and commands with VS 2005 + SP1&lt;/a&gt; it is very well explained how to solve this problem.&lt;/p&gt;  &lt;p&gt;The answer relies on the fact that every toolbar and menu is uniquely identified in Visual Studio by a &lt;span&gt;...&lt;a href="http://weblogs.asp.net/spano/archive/2008/10/07/how-to-find-visual-studio-command-bars.aspx"&gt;&lt;img style="vertical-align: text-top;" border="0" src="http://www.blogblog.com/rounders2/icon_arrow.gif" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2008/10/07/how-to-find-visual-studio-command-bars.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-2719979037721723857?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/2719979037721723857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=2719979037721723857&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/2719979037721723857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/2719979037721723857'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2008/10/how-to-find-visual-studio-command-bars.html' title='How to find Visual Studio command bars'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-7064800552161060381</id><published>2008-10-05T11:14:00.001-03:00</published><updated>2008-10-05T11:14:02.759-03:00</updated><title type='text'>CodeCamp Buenos Aires 2008</title><content type='html'>&lt;p&gt;&lt;p&gt;I attended yesterday to the &lt;a href="http://www.microsoft.com/argentina/codecamp/"&gt;Microsoft Code Camp&lt;/a&gt; event at Buenos Aires. It was fun! &lt;/p&gt;  &lt;p&gt;Here's a picture of the &lt;a href="http://www.lagash.com/"&gt;Lagash&lt;/a&gt; stand:&lt;/p&gt;  &lt;p&gt; &lt;img src="http://weblogs.asp.net/blogs/spano/CodeCamp04.JPG" /&gt;&lt;/p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2008/10/05/codecamp-buenos-aires-2008.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-7064800552161060381?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/7064800552161060381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=7064800552161060381&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/7064800552161060381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/7064800552161060381'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2008/10/codecamp-buenos-aires-2008.html' title='CodeCamp Buenos Aires 2008'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-8091197076560671881</id><published>2008-03-12T15:40:00.005-02:00</published><updated>2008-03-12T16:14:18.893-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><title type='text'>UI Automation Article Published on Level Extreme</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://weblogs.asp.net/blogs/spano/LevelExtremeMarch2008.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 134px;" src="http://weblogs.asp.net/blogs/spano/LevelExtremeMarch2008.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;p&gt;  &lt;/p&gt;On this month's edition of the &lt;a href="http://www.levelextreme.net/" mce_href="http://www.levelextreme.net/"&gt;Level Extreme .Net Magazine&lt;/a&gt;, my article about &lt;a href="http://www.levelextreme.net/ViewPageArticle.aspx?Session=3143664868567841524F303D2031476A37344564662F76543075542F4C2B70546C34513D3D" mce_href="http://www.levelextreme.net/ViewPageArticle.aspx?Session=3143664868567841524F303D2031476A37344564662F76543075542F4C2B70546C34513D3D"&gt;Building an UI Automation Client Application&lt;/a&gt; was published. The article walks through building a client application for automating a win 32 target application (the Windows Address Book). The idea is to show through simple code snippets how to use the &lt;a href="http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx" mce_href="http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx"&gt;UI Automation&lt;/a&gt; API for manipulating a target application programmatically through its UI. It shows how to find the UI elements, and how to work with the UI Automation patterns and handle events. The sample client application code contains further examples and can be downloaded from the article's page. Hope you read it!&lt;br /&gt;&lt;br /&gt;Read more on the magazine from &lt;a href="http://blog.salias.com.ar/2008/03/level-extreme-net-de-marzo.html" mce_href="http://blog.salias.com.ar/2008/03/level-extreme-net-de-marzo.html"&gt;Martin Salias&lt;/a&gt;.&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2008/03/12/ui-automation-article-published-on-level-extreme.aspx"&gt;&lt;/a&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-8091197076560671881?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/8091197076560671881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=8091197076560671881&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/8091197076560671881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/8091197076560671881'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2008/03/ui-automation-article-published-on.html' title='UI Automation Article Published on Level Extreme'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-7289103716234209347</id><published>2008-01-15T13:09:00.001-02:00</published><updated>2008-01-15T13:11:27.294-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CCF'/><title type='text'>CCF: Listening to External Application Events</title><content type='html'>&lt;p&gt;&lt;p&gt;It is often necessary to listen to external application UI events when automating applications in CCF. For example, we may need to save a value in the Context if the user presses a button, or do something when an alert dialog appears. There are many ways we can handle events. In CCF 2008, the Hosted Application Toolkit (HAT) provides an easy way to listen to them. If not using HAT we can hook to events using the UIAutomation or MSAA (Microsoft Active Accessibility) APIs within our own application adapters.&lt;span&gt;...&lt;a href="http://weblogs.asp.net/spano/archive/2008/01/15/ccf-listening-to-external-application-events.aspx"&gt;&lt;img style="vertical-align: text-top;" border="0" src="http://www.blogblog.com/rounders2/icon_arrow.gif" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2008/01/15/ccf-listening-to-external-application-events.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-7289103716234209347?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/7289103716234209347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=7289103716234209347&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/7289103716234209347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/7289103716234209347'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2008/01/ccf-listening-to-external-application.html' title='CCF: Listening to External Application Events'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-2879112452638402621</id><published>2007-12-06T22:48:00.001-03:00</published><updated>2007-12-06T22:48:57.527-03:00</updated><title type='text'>Hosting a Window Form Control in a SharePoint WebPart</title><content type='html'>&lt;p&gt;&lt;p&gt;Some months ago I posted about &lt;a href="http://weblogs.asp.net/spano/archive/2007/09/19/hosting-a-windows-form-control-in-a-web-page.aspx" mce_href="http://weblogs.asp.net/spano/archive/2007/09/19/hosting-a-windows-form-control-in-a-web-page.aspx"&gt;Hosting a Windows Form Control in a web page&lt;/a&gt;. I explained there how we can run a WinForm control from Internet Explorer by hosting it in a web page using the &amp;lt;object&amp;gt; tag. Now suppose you want to use the same solution in a custom web part that is included in a Sharepoint site. I will describe here where the control library should be placed and how it can be referenced from the web part.&lt;/p&gt;  &lt;p&gt;When we develop a custom web part, we place its resources under the _wpresources web site, into a folder named &amp;lt;WebPartAssemblyName&amp;gt;/&amp;lt;WebPartAssemblyVersion&amp;gt;__&amp;lt;PublicKeyToken&amp;gt;. You can create there a subfolder (named "bin" por example) to place the win control assembly. This folder must have execute permissions set to Script Only (not Script and Executables as is the default under a SharePoint site). The picture bellow shows the resulting structure when placing the win form control assembly in a web part called MyCustomWebPart that is part of the MyCustomWebParts assembly: &lt;span&gt;...&lt;a href="http://weblogs.asp.net/spano/archive/2007/12/06/hosting-a-window-form-control-in-a-sharepoint-webpart.aspx"&gt;&lt;img style="vertical-align: text-top;" border="0" src="http://www.blogblog.com/rounders2/icon_arrow.gif" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2007/12/06/hosting-a-window-form-control-in-a-sharepoint-webpart.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-2879112452638402621?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/2879112452638402621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=2879112452638402621&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/2879112452638402621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/2879112452638402621'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/12/hosting-window-form-control-in.html' title='Hosting a Window Form Control in a SharePoint WebPart'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-3300538164820793824</id><published>2007-10-30T22:35:00.001-03:00</published><updated>2007-10-30T22:37:00.384-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CCF'/><title type='text'>CCF HAT - Making use of DDAs from Legacy Adapters</title><content type='html'>&lt;p&gt;&lt;p&gt;Although Data Driven Adapters (DDAs) are mainly designed for Automation Adapters in HAT, we can make use of them from legacy adapters, too. Here's an example of an external VB application, which is configured to use a legacy application adapter and a WinDataDrivenAdapter with the corresponding bindings:&lt;/p&gt;  &lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red255\green0\blue0;\red0\green0\blue0;}??\fs20 \cf1 &amp;lt;?\cf3 xml\cf1  \cf4 version\cf1 =\cf0 "\cf1 1.0\cf0 "\cf1  \cf4 encoding\cf1 =\cf0 "\cf1 utf-16\cf0 "\cf1 ?&amp;gt;\par ??&amp;lt;\cf3 initstring\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 interopAssembly\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 URL\cf1 &amp;gt;\cf0 C:\\MyApp.exe\cf1 &amp;lt;/\cf3 URL\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 WorkingDirectory\cf1 &amp;gt;\cf0 C:\\\cf1 &amp;lt;/\cf3 WorkingDirectory\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 hostInside\cf1  /&amp;gt;\par ??\tab &amp;lt;/\cf3 interopAssembly\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 UseTopLevelWindow\cf1  \cf4 class\cf1 =\cf0 "\cf1 ThunderRT6Form\cf0 "\cf1  /&amp;gt;\par ??\tab &amp;lt;\cf3 adapter\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 URL\cf1 &amp;gt;\cf0 C:\\MyApplicationAdapters.dll\cf1 &amp;lt;/\cf3 URL\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 type\cf1 &amp;gt;\cf0 Microsoft.Ccf.QuickStarts.MyExtVBAppAdapter\cf1 &amp;lt;/\cf3 type\cf1 &amp;gt;\par ??\tab &amp;lt;/\cf3 adapter\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 DataDrivenAdapterBindings\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 Type\cf1 &amp;gt;\cf0 Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter.WinDataDrivenAdapter, \par ??\tab \tab \tab   Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter\cf1 &amp;lt;/\cf3 Type\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 Controls\cf1 &amp;gt;\par ??\tab \tab \tab &amp;lt;\cf3 AccControl\cf1  \cf4 name\cf1 =\cf0 "\cf1 button1\cf0 "\cf1 &amp;gt;\par ??\tab \tab \tab \tab &amp;lt;\cf3 Path\cf1 &amp;gt;\par ??\tab \tab \tab \tab \tab &amp;lt;\cf3 Next\cf1 &amp;gt;\cf0 OK\cf1 &amp;lt;/\cf3 Next\cf1 &amp;gt;\par ??\tab \tab \tab \tab &amp;lt;/\cf3 Path\cf1 &amp;gt;\par ??\tab \tab \tab &amp;lt;/\cf3 AccControl\cf1 &amp;gt;\par ??\tab \tab &amp;lt;/\cf3 Controls\cf1 &amp;gt;\par ??\tab &amp;lt;/\cf3 DataDrivenAdapterBindings\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 optimumSize\cf1  \cf4 x\cf1 =\cf0 "\cf1 800\cf0 "\cf1  \cf4 y\cf1 =\cf0 "\cf1 600\cf0 "\cf1  /&amp;gt;\par ??\tab &amp;lt;\cf3 minimumSize\cf1  \cf4 x\cf1 =\cf0 "\cf1 640\cf0 "\cf1  \cf4 y\cf1 =\cf0 "\cf1 480\cf0 "\cf1  /&amp;gt;\par ??&amp;lt;/\cf3 initstring\cf1 &amp;gt;}&lt;br /&gt;--&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }&lt;br /&gt;.cl { margin: 0px; }&lt;br /&gt;.cb1 { color: blue; }&lt;br /&gt;.cb2 { color: #a31515; }&lt;br /&gt;.cb3 { color: red; }&lt;/style&gt;&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="cb2"&gt;xml&lt;/span&gt;&lt;span class="cb1"&gt; &lt;/span&gt;&lt;span class="cb3"&gt;version&lt;/span&gt;&lt;span class="cb1"&gt;=&lt;/span&gt;"&lt;span class="cb1"&gt;1.0&lt;/span&gt;"&lt;span class="cb1"&gt; &lt;/span&gt;&lt;span class="cb3"&gt;encoding&lt;span&gt;...&lt;a href="http://weblogs.asp.net/spano/archive/2007/10/30/ccf-hat-making-use-of-ddas-from-legacy-adapters.aspx"&gt;&lt;img style="vertical-align: text-top;" border="0" src="http://www.blogblog.com/rounders2/icon_arrow.gif" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2007/10/30/ccf-hat-making-use-of-ddas-from-legacy-adapters.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-3300538164820793824?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/3300538164820793824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=3300538164820793824&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/3300538164820793824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/3300538164820793824'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/10/ccf-hat-making-use-of-ddas-from-legacy.html' title='CCF HAT - Making use of DDAs from Legacy Adapters'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-981721841488743700</id><published>2007-10-26T00:40:00.001-03:00</published><updated>2007-10-26T10:37:49.714-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CCF'/><title type='text'>CCF 2008 Hosted Application Toolkit</title><content type='html'>&lt;p&gt;&lt;/p&gt;&lt;p&gt;The Hosted Application Toolkit (HAT) is a new component of CCF 2.6 (2008) that facilitates the task of automating the UI of the hosted applications. It consists of two main parts: the Data Driven Adapters (DDA) and the Automations (WF workflows) that automates the hosted application using the DDAs.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Data Driven Adapters&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;DDAs must inherit from DataDrivenAdapterBase in Microsoft.Ccf.HostedApplicationToolkit. CCF supports two implementations out of the box: WinDataDrivenAdapter and WebDataDrivenAdapter. We can inherit from any of the three to extend the DDA as necessary. The methods the DDAs expose to manipulate the hosted application UI are ExecuteControlAction, FindControl, GetControlValue and SetControlValue. These methods take a friendly name as parameter and lets the application adapters interact with the hosted application UI abstracting from the details of how to obtain the control from that friendly name. The mapping between the controls' friendly names and the directions for the DDA to finding them is called Data Driven Adapter Binding and is part of the hosted app initialization string:&lt;span&gt;...&lt;a href="http://weblogs.asp.net/spano/archive/2007/10/26/ccf-2008-hosted-application-toolkit.aspx"&gt;&lt;img style="vertical-align: text-top;" src="http://www.blogblog.com/rounders2/icon_arrow.gif" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2007/10/26/ccf-2008-hosted-application-toolkit.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-981721841488743700?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/981721841488743700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=981721841488743700&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/981721841488743700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/981721841488743700'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/10/ccf-2008-hosted-application-toolkit.html' title='CCF 2008 Hosted Application Toolkit'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-1874009206575963481</id><published>2007-10-08T10:12:00.001-03:00</published><updated>2007-10-08T15:10:23.133-03:00</updated><title type='text'>Silverlight article published this month</title><content type='html'>&lt;p align="left"&gt;My colleagues &lt;a href="http://weblogs.asp.net/arielneisen" mce_href="http://weblogs.asp.net/arielneisen"&gt;Ariel Neisen&lt;/a&gt;, Federico García, &lt;a href="http://weblogs.shockbyte.com.ar/rodolfof" mce_href="http://weblogs.shockbyte.com.ar/rodolfof"&gt;Rodolfo Finochietti&lt;/a&gt; and I wrote the cover article of the &lt;a href="http://www.redusers.com/noticias/code-42" mce_href="http://www.redusers.com/noticias/code-42"&gt;#42 edition of the .Code Magazine&lt;/a&gt; (in Spanish) about &lt;strong&gt;Silverlight&lt;/strong&gt;. The article talks about this new technology's fundamentals, architecture, programming tools, advanced features, code samples and a lot more. &lt;/p&gt;&lt;p align="center"&gt;&lt;img id="id" src="http://weblogs.asp.net/blogs/spano/tapa-code-42.gif" /&gt; &lt;/p&gt;&lt;p align="left"&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-1874009206575963481?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/1874009206575963481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=1874009206575963481&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/1874009206575963481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/1874009206575963481'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/10/silverlight-article-published-this.html' title='Silverlight article published this month'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-4389003688813433091</id><published>2007-10-01T23:49:00.001-03:00</published><updated>2007-10-02T00:02:01.278-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Choosing the right WCF binding</title><content type='html'>&lt;p&gt;&lt;p&gt;A WCF binding is the endpoint component that defines &lt;em&gt;how&lt;/em&gt; the client needs to communicate with the service. It groups settings such as underlying transport protocol, security requirements, and message encoding.&lt;/p&gt;  &lt;p&gt;WCF provides nine built-in bindings: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;BasicHttpBinding&lt;/strong&gt;: Basic web service communication. Exposes WCF services as legacy ASMX web services. Used for interoperability. No security by default.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;WSHttpBinding&lt;/strong&gt;: Web services with WS-* support. Supports transactions and reliable messaging.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;WSDualHttpBinding&lt;span&gt;...&lt;a href="http://weblogs.asp.net/spano/archive/2007/10/02/choosing-the-right-wcf-binding.aspx"&gt;&lt;img style="vertical-align: text-top;" border="0" src="http://www.blogblog.com/rounders2/icon_arrow.gif" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2007/10/02/choosing-the-right-wcf-binding.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-4389003688813433091?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/4389003688813433091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=4389003688813433091&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4389003688813433091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4389003688813433091'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/10/choosing-right-wcf-binding.html' title='Choosing the right WCF binding'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-4073892672552540852</id><published>2007-09-28T14:01:00.001-03:00</published><updated>2007-10-02T00:02:24.593-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CCF'/><title type='text'>CCF 2008 New Features</title><content type='html'>&lt;p&gt;&lt;p&gt;The 3.0 version of the Customer Care Framework (CCF) is out! Among its &lt;a href="http://blogs.msdn.com/ypitsch/archive/2007/09/21/ccf-2008-is-there.aspx"&gt;new features&lt;/a&gt; we'll find: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;CCF web services migrated to Windows Communication Foundation (WCF). &lt;/li&gt;    &lt;li&gt;Agent Desktop use of Composite Application Block (CAB). &lt;/li&gt;    &lt;li&gt;Hosted Application Toolkit (HAT): new sub-system for providing UI automation, that makes use of Workflow Foundation (WF) and Active Accessibility. &lt;/li&gt;    &lt;li&gt;ClickOnce support. &lt;/li&gt;    &lt;li&gt;Dynamic Applications: 3rd category of hosted applications that allow an agent to dynamically launch or close a hosted application on-demand, via the UI or programmatically in code. &lt;span&gt;...&lt;a href="http://weblogs.asp.net/spano/archive/2007/09/28/ccf-2008-new-features.aspx"&gt;&lt;img style="vertical-align: text-top;" border="0" src="http://www.blogblog.com/rounders2/icon_arrow.gif" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2007/09/28/ccf-2008-new-features.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-4073892672552540852?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/4073892672552540852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=4073892672552540852&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4073892672552540852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4073892672552540852'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/09/ccf-2008-new-features.html' title='CCF 2008 New Features'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-6336928166301900143</id><published>2007-09-28T00:26:00.001-03:00</published><updated>2007-09-28T00:27:18.795-03:00</updated><title type='text'>Hosting a Windows Form Control in a web page</title><content type='html'>&lt;p&gt;Although it is not the most common use of it, it is possible to host a Windows Form Control in a Web Page and run it from within Internet Explorer. This allows to build powerful client side functionality with all the advantages of using the .Net framework and executing the control in the client side. Of course there are some restrictions that cannot be left aside. At least the .Net framework must be installed on the client for the control to run. In addition, it is possible that some permission must...&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2007/09/19/hosting-a-windows-form-control-in-a-web-page.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-6336928166301900143?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/6336928166301900143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=6336928166301900143&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/6336928166301900143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/6336928166301900143'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/09/hosting-windows-form-control-in-web.html' title='Hosting a Windows Form Control in a web page'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-4927434076108648660</id><published>2007-09-28T00:24:00.001-03:00</published><updated>2007-10-02T00:03:01.388-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><title type='text'>WPF Accessibility</title><content type='html'>&lt;p&gt;Windows Presentation Foundation (WPF) provides a very interesting API for Accessibility called &lt;strong&gt;Microsoft UI Automation&lt;/strong&gt;. It allows programmatic access to most user interface elements on the desktop, addressing the needs of assistive technology products and also for User Interface (UI) tests automation. &lt;/p&gt;  &lt;p&gt;The framework provides solutions for both accessibility providers and clients, and it is conformed of four main components (see &lt;a href="http://msdn2.microsoft.com/en-us/library/ms747327.aspx"&gt;UI Automation Overview&lt;/a&gt;): &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The &lt;strong&gt;Provider API&lt;/strong&gt; (UIAutomationProvider.dll and UIAutomationTypes.dll) defines a ...&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx"&gt;Read full article&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-4927434076108648660?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/4927434076108648660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=4927434076108648660&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4927434076108648660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4927434076108648660'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/09/wpf-accessibility.html' title='WPF Accessibility'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-3422349807466235806</id><published>2007-09-28T00:17:00.001-03:00</published><updated>2007-09-28T00:17:45.387-03:00</updated><title type='text'>Also blogging @ weblogs.asp.net</title><content type='html'>&lt;p&gt;Earlier this month I opened an account to start blogging at weblogs.asp.net. I moved the latest contents from here to there, and I will be cross-posting future entries to have both blogs synchronized. Check it out: &lt;a title="http://weblogs.asp.net/spano/" href="http://weblogs.asp.net/spano/"&gt;http://weblogs.asp.net/spano/&lt;/a&gt;.&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-3422349807466235806?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/3422349807466235806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=3422349807466235806&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/3422349807466235806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/3422349807466235806'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/09/also-blogging-weblogsaspnet.html' title='Also blogging @ weblogs.asp.net'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-2339214795674021539</id><published>2007-06-10T20:42:00.001-03:00</published><updated>2008-12-10T22:59:21.413-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Office add-ins'/><title type='text'>Working around VSTO SE's lack of document-customization for Excel 2007</title><content type='html'>I've been doing some research on &lt;a href="http://msdn2.microsoft.com/en-us/office/aa905533.aspx"&gt;Visual Studio Tools for Office (VSTO)&lt;/a&gt;  and Excel 2007 recently and found out that some very interesting features available in previous versions of VSTO for Excel 2003 are not available for Excel 2007. Here's a summary of the current situation and the workarounds I figured out. &lt;p&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;State of the Art&lt;/strong&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;VSTO has basically two kinds of Excel add-ins: document-level customization an application-level add-ins. &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;The &lt;strong&gt;document-level customization&lt;/strong&gt; lets you customize an Excel workbook and also reference the Application to add buttons to the command bar and so forth. The resulting add-in will be only available to the customized workbook. The great benefit of document-level customization is that you can add controls to the spreadsheets within Visual Studio, being these controls part of the VSTO object model. The VSTO objects are wrappers around the Interop ones and they add very interesting functionality, like events and databinding. The VSTO controls are in the Microsoft.Office.Tools.Excel namespace whereas the Interop ones are in Microsoft.Office.Interop.Excel.&lt;/p&gt; &lt;p face="arial" style="text-align: center; font-weight: bold;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_vRmmMCC9gL0/RmyPTtkDxgI/AAAAAAAAABI/D_MAjuk0EWE/s1600-h/excelWorkbook1.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_vRmmMCC9gL0/RmyPTtkDxgI/AAAAAAAAABI/D_MAjuk0EWE/s320/excelWorkbook1.JPG" alt="" id="BLOGGER_PHOTO_ID_5074588448950830594" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: center; font-family: arial; font-weight: bold;"&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Document-level customization project template&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="text-align: center; font-weight: bold;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_vRmmMCC9gL0/RmyPfdkDxhI/AAAAAAAAABQ/rgEnBD0Nq7I/s1600-h/excelWorkbook2.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_vRmmMCC9gL0/RmyPfdkDxhI/AAAAAAAAABQ/rgEnBD0Nq7I/s320/excelWorkbook2.JPG" alt="" id="BLOGGER_PHOTO_ID_5074588650814293522" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-weight: bold;"&gt;Document-level customization project&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;On the other and, an &lt;strong&gt;application-level add-in&lt;/strong&gt; is, as its name implies, always visible for the host Application regardless of the opened workbook. The only class added by Visual Studio is the TheAddin one, no workbook or worksheet editors are provided. The VSTO controls are not available neither. All Excel objects that we can get access through TheAddin class are from the Microsoft.Office.Interop.Excel API.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_vRmmMCC9gL0/RmyPqdkDxiI/AAAAAAAAABY/Xc-ep1cZVoI/s1600-h/exceladdin1.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_vRmmMCC9gL0/RmyPqdkDxiI/AAAAAAAAABY/Xc-ep1cZVoI/s320/exceladdin1.JPG" alt="" id="BLOGGER_PHOTO_ID_5074588839792854562" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: center; font-weight: bold;"&gt;&lt;span style="font-size:78%;"&gt;Application-level add-in project template&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_vRmmMCC9gL0/RmyPvtkDxjI/AAAAAAAAABg/Mls4ceGD-80/s1600-h/exceladdin2.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_vRmmMCC9gL0/RmyPvtkDxjI/AAAAAAAAABg/Mls4ceGD-80/s320/exceladdin2.JPG" alt="" id="BLOGGER_PHOTO_ID_5074588929987167794" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p style="font-weight: bold; text-align: center;"&gt;&lt;span style="font-size:78%;"&gt;Application-level add-in project&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;The problem is that, whereas document-level customization is available for Excel2003, is not yet available for Excel 2007. So, the spreadsheet editor is not available within Visual Studio and the VSTO extended controls cannot be used. The table below shows which kinds of add-in are available for each product combination (see &lt;a href="http://msdn2.microsoft.com/en-us/library/aa942839%28VS.80%29.aspx"&gt;Features available by product combination&lt;/a&gt; for the complete table listing all Office applications).&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;table border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;VSTO 2005 or Visual Studio Team System&lt;/td&gt; &lt;td&gt;VSTO 2005 SE installed with VSTO 2005 or Visual Studio Team System&lt;/td&gt; &lt;td&gt;VSTO 2005 SE installed with Visual Studio 2005 Professional Edition&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Document-level customizations&lt;/td&gt; &lt;td&gt;Excel 2003&lt;/td&gt; &lt;td&gt;Excel 2003&lt;/td&gt; &lt;td&gt;Not available&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Application-level add-ins&lt;/td&gt; &lt;td&gt;Not available&lt;/td&gt; &lt;td&gt; &lt;p&gt;Excel 2003 &lt;/p&gt; &lt;p&gt;Excel 2007&lt;/p&gt;&lt;/td&gt; &lt;td&gt; &lt;p&gt;Excel 2003 &lt;/p&gt; &lt;p&gt;Excel 2007&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Workarounds&lt;/strong&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;In order to make a document-level customization (or at least something similar) to target Excel 2007 I found out that some of the following things can be done:&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;1- Develop for Excel 2003 and deploy in Excel 2007&lt;/p&gt; &lt;p&gt;It is possible to develop a document-level customization in Visual Studio for Excel 2003 using VSTO 2005. The resulting customized document can then be opened in Excel 2007 in compatibility mode with the same functionality. The drawbacks of this approach is that Excel 2003 needs to be installed in the developer's machine and that you won't have Office 2007 features like custom panes and ribbon extensibility available.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;2- Develop for Excel 2007 with VSTO SE and try to emulate the document-level customization.&lt;/p&gt; &lt;p&gt; In order to target Excel 2007, VSTO SE is needed and the only option by the moment is to create an application level add-in. For emulating the document customization you can create an Excel's template file within Excel application, add the desired named ranges, tables, graphics, etc...and then access these controls trough the add-in's code to make custom automation. The drawback of this approach is that the extended functionality of VSTO's controls is not available. For example, you won't be able to use the ListObject databinding support. In order to access the workbook controls, the Interop API must be used. Another drawback, is that the Interop API is not as well documented as the VSTO's.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;3- Develop an application-level add-in for Excel 2007 and create the VSTO's objects from code.&lt;/p&gt; &lt;p&gt;Actually I'm not sure wheter this is really a choice, since I couldn't make it work. What I tried here was to create a new instance of a VSTO worksheet to wrap an Interop worksheet. In ThisAddin class I have the following code:&lt;/p&gt; &lt;p&gt;&lt;!-- {\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 using\cf0  Excel = Microsoft.Office.Interop.Excel;\par ??\cf2 using\cf0  Vsto = Microsoft.Office.Tools.Excel;\par ??\par ??\cf2 namespace\cf0  ExcelAddIn1\par ??\{\par ??    \cf2 public\cf0  \cf2 partial\cf0  \cf2 class\cf0  \cf10 ThisAddIn\par ??\cf0     \{\par ??        \cf2 private\cf0  \cf2 void\cf0  ThisAddIn_Startup(\cf2 object\cf0  sender, System.\cf10 EventArgs\cf0  e)\par ??        \{\par ??\cf2             #region\cf0  VSTO generated code\par ??\par ??            \cf2 this\cf0 .Application = (Excel.\cf10 Application\cf0 )Microsoft.Office.Tools.Excel.\cf10 ExcelLocale1033Proxy\cf0 .Wrap(\cf2 typeof\cf0 (Excel.\cf10 Application\cf0 ), \cf2 this\cf0 .Application);\par ??\par ??\cf2             #endregion\par ??\par ??\cf0             \cf2 try\par ??\cf0             \{\par ??                Excel.\cf10 Worksheet\cf0  newSheet = (Excel.\cf10 Worksheet\cf0 )\cf2 this\cf0 .Application.ActiveWorkbook.Worksheets.Add(\cf10 Type\cf0 .Missing, \cf10 Type\cf0 .Missing, \cf10 Type\cf0 .Missing, \cf10 Type\cf0 .Missing);\par ??                Microsoft.Office.Tools.Excel.\cf10 Worksheet\cf0  extendedSheet = GetExtendedWorksheet(newSheet);\par ??                extendedSheet.Controls.AddNamedRange(extendedSheet.Range[\cf13 "A1"\cf0 ,\cf13 "C2"\cf0 ], \cf13 "NamedRange"\cf0 );\par ??            \}\par ??            \cf2 catch\cf0  (\cf10 Exception\cf0  ex) \{\par ??                \cf10 MessageBox\cf0 .Show(ex.ToString());\par ??            \}\par ??        \}\par ??\par ??        \cf2 private\cf0  Vsto.\cf10 Worksheet\cf0  GetExtendedWorksheet(Excel.\cf10 Worksheet\cf0  nativeWorksheet)\par ??        \{\par ??            \cf11 //Get the IHostItemProvider instance.\par ??\cf0             Microsoft.VisualStudio.Tools.Applications.Runtime.\cf10 IHostItemProvider\cf0  hostItemProvider = (Microsoft.VisualStudio.Tools.Applications.Runtime.\cf10 IHostItemProvider\cf0 )\par ??                RuntimeCallback.GetService(\cf2 typeof\cf0 (Microsoft.VisualStudio.Tools.Applications.Runtime.\cf10 IHostItemProvider\cf0 ));\par ??            \cf11 //Create the new worksheet and return it to calling function.\par ??\cf0             \cf2 return\cf0  \cf2 new\cf0  Vsto.\cf10 Worksheet\cf0 (hostItemProvider, RuntimeCallback, nativeWorksheet.CodeName,\par ??               \cf2 null\cf0 , nativeWorksheet.Name);\par ??        \}} --&gt; &lt;/p&gt;&lt;div    style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:courier new;font-size:10pt;color:black;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&lt;/span&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; Excel = Microsoft.Office.Interop.Excel;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; Vsto = Microsoft.Office.Tools.Excel;&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;namespace&lt;/span&gt; ExcelAddIn1&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;partial&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:teal;"&gt;ThisAddIn&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ThisAddIn_Startup(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, System.&lt;span style="color:teal;"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;            #region&lt;/span&gt; VSTO generated code&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color:blue;"&gt;this&lt;/span&gt;.Application = (Excel.&lt;span style="color:teal;"&gt;Application&lt;/span&gt;)Microsoft.Office.Tools.Excel.&lt;span style="color:teal;"&gt;ExcelLocale1033Proxy&lt;/span&gt;.Wrap(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(Excel.&lt;span style="color:teal;"&gt;Application&lt;/span&gt;), &lt;span style="color:blue;"&gt;this&lt;/span&gt;.Application);&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;            #endregion&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color:blue;"&gt;try&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                Excel.&lt;span style="color:teal;"&gt;Worksheet&lt;/span&gt; newSheet = (Excel.&lt;span style="color:teal;"&gt;Worksheet&lt;/span&gt;)&lt;span style="color:blue;"&gt;this&lt;/span&gt;.Application.ActiveWorkbook.Worksheets.Add(&lt;span style="color:teal;"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color:teal;"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color:teal;"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color:teal;"&gt;Type&lt;/span&gt;.Missing);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                Microsoft.Office.Tools.Excel.&lt;span style="color:teal;"&gt;Worksheet&lt;/span&gt; extendedSheet = GetExtendedWorksheet(newSheet);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                extendedSheet.Controls.AddNamedRange(extendedSheet.Range[&lt;span style="color:maroon;"&gt;"A1"&lt;/span&gt;,&lt;span style="color:maroon;"&gt;"C2"&lt;/span&gt;], &lt;span style="color:maroon;"&gt;"NamedRange"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color:blue;"&gt;catch&lt;/span&gt; (&lt;span style="color:teal;"&gt;Exception&lt;/span&gt; ex) {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                &lt;span style="color:teal;"&gt;MessageBox&lt;/span&gt;.Show(ex.ToString());&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        }&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color:blue;"&gt;private&lt;/span&gt; Vsto.&lt;span style="color:teal;"&gt;Worksheet&lt;/span&gt; GetExtendedWorksheet(Excel.&lt;span style="color:teal;"&gt;Worksheet&lt;/span&gt; nativeWorksheet)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color:green;"&gt;//Get the IHostItemProvider instance.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            Microsoft.VisualStudio.Tools.Applications.Runtime.&lt;span style="color:teal;"&gt;IHostItemProvider&lt;/span&gt; hostItemProvider = (Microsoft.VisualStudio.Tools.Applications.Runtime.&lt;span style="color:teal;"&gt;IHostItemProvider&lt;/span&gt;)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                RuntimeCallback.GetService(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(Microsoft.VisualStudio.Tools.Applications.Runtime.&lt;span style="color:teal;"&gt;IHostItemProvider&lt;/span&gt;));&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color:green;"&gt;//Create the new worksheet and return it to calling function.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; Vsto.&lt;span style="color:teal;"&gt;Worksheet&lt;/span&gt;(hostItemProvider, RuntimeCallback, nativeWorksheet.CodeName,&lt;/p&gt; &lt;p style="margin: 0px;"&gt;               &lt;span style="color:blue;"&gt;null&lt;/span&gt;, nativeWorksheet.Name);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        }&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;But, when trying to add the NamedRange to the extended worksheet this Exception is thrown:&lt;/p&gt;  &lt;p&gt;&lt;span style=";font-family:Courier New;font-size:85%;"  &gt;&lt;em&gt;This document might not function as expected because the following control is missing: Sheet4. Data that relies on this control will not be automatically displayed or updated, and other custom functionality will not be available. Contact your administrator or the author of this document for further assistance.&lt;br /&gt;at Microsoft.Office.Tools.Excel.Worksheet.GetObjects()&lt;br /&gt;at Microsoft.Office.Tools.Excel.Worksheet.GetPrimaryControl()&lt;br /&gt;at Microsoft.Office.Tools.Excel.Worksheet.get_Range()&lt;br /&gt;at ExcelAddIn1.ThisAddIn.ThisAddIn_Startup(Object sender, EventArgs e) in C:\...\Projects\ExcelAddIn1\ExcelAddIn1\ThisAddIn.cs:line 26&lt;/em&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;  &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Although VSTO's document-level customization is not available for Excel 2007 yet, there still are some choices for developing add-ins targeting this application version. Besides, the good news is that this lack will be supplied soon. VSTO "Orcas" will provide document-level customization for Excel 2007 within its new features. So, anyway, it's just a matter of time...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-2339214795674021539?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/2339214795674021539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=2339214795674021539&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/2339214795674021539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/2339214795674021539'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/06/working-around-vsto-se-lack-of-document.html' title='Working around VSTO SE&amp;#39;s lack of document-customization for Excel 2007'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_vRmmMCC9gL0/RmyPTtkDxgI/AAAAAAAAABI/D_MAjuk0EWE/s72-c/excelWorkbook1.JPG' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-3096229791054885153</id><published>2007-05-16T14:03:00.001-03:00</published><updated>2007-05-16T14:53:13.489-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entlib'/><title type='text'>Developing a Custom Property Comparison Validator using Entlib's VAP</title><content type='html'>&lt;p&gt;&amp;nbsp;Here's a sample scenario where, in an application using Entlib's Validation Application Block (VAP), the validation of an entity's member depends on the value of &amp;nbsp;another property. In this case the entity I want to validate has two properties. Using the attributes approach to support validation, the entity's code looks like this:&lt;/p&gt; &lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 public\cf0  \cf2 class\cf0  \cf10 MyEntity\par ??\cf0 \{\par ??    \cf2 private\cf0  \cf2 string\cf0  myVar1;\par ??\par ??    [\cf10 NotNullValidator\cf0 ()]\par ??    [\cf10 StringLengthValidator\cf0 (0, 20, MessageTemplate = \cf13 "MyProperty1 must be less than 20 characters length"\cf0 )]\par ??    \cf2 public\cf0  \cf2 string\cf0  MyProperty1\par ??    \{\par ??        \cf2 get\cf0  \{ \cf2 return\cf0  myVar1; \}\par ??        \cf2 set\cf0  \{ myVar1 = \cf2 value\cf0 ; \}\par ??    \}\par ??\par ??    \cf2 private\cf0  \cf2 string\cf0  myVar2;\par ??\par ??    [\cf10 MyProp2Validator\cf0 ()]\par ??    \cf2 public\cf0  \cf2 string\cf0  MyProperty2\par ??    \{\par ??        \cf2 get\cf0  \{ \cf2 return\cf0  myVar2; \}\par ??        \cf2 set\cf0  \{ myVar2 = \cf2 value\cf0 ; \}\par ??    \}\par ??\}}&lt;br /&gt;--&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: teal"&gt;MyEntity&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; myVar1;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: teal"&gt;NotNullValidator&lt;/span&gt;()]&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: teal"&gt;StringLengthValidator&lt;/span&gt;(0, 20, MessageTemplate = &lt;span style="color: maroon"&gt;"MyProperty1 must be less than 20 characters length"&lt;/span&gt;)]&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; MyProperty1&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; myVar1; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;set&lt;/span&gt; { myVar1 = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; myVar2;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: teal"&gt;MyProp2Validator&lt;/span&gt;()]&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; MyProperty2&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; myVar2; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;set&lt;/span&gt; { myVar2 = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;The validators for Property1 are built in validators, no big deal with that. The thing here is that I want the second property to be validated against the value of the first one. Let’s say, for example, that Property2 is valid if it begins with the value of Property1. &lt;/p&gt; &lt;p&gt;Although the VAP ships with a &lt;strong&gt;PropertyComparisonValidator&lt;/strong&gt;, it is limited to comparisons of type =, !=, &amp;gt;, &amp;gt;=, &amp;lt;&amp;gt;. So it seems that a custom validator has to be made. But how to obtain the actual value of Property1 from the Property2's custom validator?  &lt;p&gt;One approach is to use reflection. Using reflection the DoValidate method of MyProperty2Validator would look something like this:  &lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 protected\cf0  \cf2 override\cf0  \cf2 void\cf0  DoValidate(\cf2 string\cf0  objectToValidate, \cf2 object\cf0  currentTarget, \cf2 string\cf0  key, ValidationResults validationResults)\{\par ??    \cf11 //obtain the other property value through reflection\par ??\cf0     PropertyInfo prop = currentTarget.GetType().GetProperty(\cf13 "MyProperty1"\cf0 );\par ??    \cf2 string\cf0  myProp1Value = prop.GetValue(currentTarget, \cf2 null\cf0 ) \cf2 as\cf0  \cf2 string\cf0 ;\par ??    \cf11 //some custom logic here\par ??\cf0     \cf2 if\cf0  (! objectToValidate.StartsWith( myProp1Value )\{\par ??         LogValidationResult(validationResults,\cf13 "msg"\cf0 ,currentTarget,key);\par ??    \}\par ??\}}&lt;br /&gt;--&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DoValidate(&lt;span style="color: blue"&gt;string&lt;/span&gt; objectToValidate, &lt;span style="color: blue"&gt;object&lt;/span&gt; currentTarget, &lt;span style="color: blue"&gt;string&lt;/span&gt; key, ValidationResults validationResults){&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;//obtain the other property value through reflection&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PropertyInfo prop = currentTarget.GetType().GetProperty(&lt;span style="color: maroon"&gt;"MyProperty1"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; myProp1Value = prop.GetValue(currentTarget, &lt;span style="color: blue"&gt;null&lt;/span&gt;) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;//some custom logic here&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (! objectToValidate.StartsWith( myProp1Value ){&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; LogValidationResult(validationResults,&lt;span style="color: maroon"&gt;"msg"&lt;/span&gt;,currentTarget,key);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;But the dropdown of using reflection is that it wouldn't work with UI integration.  &lt;p&gt;What do work with integration is what the built-in PropertyComparisonValidator does, and that is using the &lt;strong&gt;ValueAccess&lt;/strong&gt; class. The ValueAccess class allow us to find other members in an integration friendly way throuhg its GetValue method. See how this is done in our Property2 valdiator:  &lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 [\cf10 ConfigurationElementType\cf0 (\cf2 typeof\cf0 (\cf10 MyProp2ValidatorData\cf0 ))]\par ??\cf2 class\cf0  \cf10 MyProp2Validator\cf0  : \cf10 Validator\cf0 &amp;lt;\cf2 string\cf0 &amp;gt; \{\par ??    \cf2 private\cf0  \cf10 ValueAccess\cf0  valueAccess;\par ??    \cf2 internal\cf0  \cf2 const\cf0  \cf2 string\cf0  OtherPropName = \cf13 "MyProperty1"\cf0 ;\par ??\par ??    \cf2 public\cf0  MyProp2Validator(\cf10 ValueAccess\cf0  valueAccess):\cf2 base\cf0  (\cf10 Resources\cf0 .MyProp2ValidatorMessageTemplate,\cf2 null\cf0 )\{\par ??        \cf2 this\cf0 .valueAccess = valueAccess;\par ??    \}\par ??\par ??    \cf2 protected\cf0  \cf2 override\cf0  \cf2 void\cf0  DoValidate(\cf2 string\cf0  objectToValidate, \cf2 object\cf0  currentTarget, \cf2 string\cf0  key, \cf10 ValidationResults\cf0  validationResults)\{\par ??        \cf2 object\cf0  myProp1;\par ??        \cf2 string\cf0  valueAccessFailureMessage;\par ??        \cf11 //try to obtain the value of property 1.\par ??\cf0         \cf2 if\cf0  (!\cf2 this\cf0 .valueAccess.GetValue(currentTarget, \cf2 out\cf0  myProp1, \cf2 out\cf0  valueAccessFailureMessage)) \{\par ??            \cf2 base\cf0 .LogValidationResult(validationResults, \cf2 string\cf0 .Format(\cf10 CultureInfo\cf0 .CurrentUICulture, \cf10 Resources\cf0 .MyProp2ValidatorFailureToRetrieveProp1, \cf2 new\cf0  \cf2 object\cf0 [] \{ \cf2 this\cf0 .valueAccess.Key, valueAccessFailureMessage \}), currentTarget, key);\par ??        \}\par ??        \cf2 else\cf0  \{\par ??            \cf11 //custom validation logic between prop1 and prop2\par ??\cf0             \cf2 if\cf0  (!objectToValidate.StartsWith((\cf2 string\cf0 )myProp1)) \{ \par ??                \cf2 base\cf0 .LogValidationResult(validationResults, \cf2 string\cf0 .Format(\cf10 CultureInfo\cf0 .CurrentUICulture, \cf2 this\cf0 .MessageTemplate, \cf2 new\cf0  \cf2 object\cf0 [] \{ objectToValidate, myProp1 \}), currentTarget, key);\par ??            \}\par ??        \}\par ??    \}\par ??\par ??    \cf2 protected\cf0  \cf2 override\cf0  \cf2 string\cf0  DefaultMessageTemplate \{\par ??        \cf2 get\cf0  \{ \cf2 return\cf0  \cf10 Resources\cf0 .MyProp2ValidatorDefaultMessageTemplate; \}\par ??    \}\par ??\}\par ??}&lt;br /&gt;--&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;p style="margin: 0px"&gt;[&lt;span style="color: teal"&gt;ConfigurationElementType&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: teal"&gt;MyProp2ValidatorData&lt;/span&gt;))]&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: teal"&gt;MyProp2Validator&lt;/span&gt; : &lt;span style="color: teal"&gt;Validator&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: teal"&gt;ValueAccess&lt;/span&gt; valueAccess;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;internal&lt;/span&gt; &lt;span style="color: blue"&gt;const&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; OtherPropName = &lt;span style="color: maroon"&gt;"MyProperty1"&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; MyProp2Validator(&lt;strong&gt;&lt;span style="color: teal"&gt;ValueAccess&lt;/span&gt; valueAccess&lt;/strong&gt;):&lt;span style="color: blue"&gt;base&lt;/span&gt; (&lt;span style="color: teal"&gt;Resources&lt;/span&gt;.MyProp2ValidatorMessageTemplate,&lt;span style="color: blue"&gt;null&lt;/span&gt;){&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.valueAccess = valueAccess;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DoValidate(&lt;span style="color: blue"&gt;string&lt;/span&gt; objectToValidate, &lt;span style="color: blue"&gt;object&lt;/span&gt; currentTarget, &lt;span style="color: blue"&gt;string&lt;/span&gt; key, &lt;span style="color: teal"&gt;ValidationResults&lt;/span&gt; validationResults){&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;object&lt;/span&gt; myProp1;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; valueAccessFailureMessage;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;//try to obtain the value of property 1.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (!&lt;span style="color: blue"&gt;this&lt;/span&gt;.&lt;strong&gt;valueAccess.GetValue&lt;/strong&gt;(currentTarget, &lt;span style="color: blue"&gt;out&lt;/span&gt; myProp1, &lt;span style="color: blue"&gt;out&lt;/span&gt; valueAccessFailureMessage)) {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;.LogValidationResult(validationResults, &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: teal"&gt;CultureInfo&lt;/span&gt;.CurrentUICulture, &lt;span style="color: teal"&gt;Resources&lt;/span&gt;.MyProp2ValidatorFailureToRetrieveProp1, &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;object&lt;/span&gt;[] { &lt;span style="color: blue"&gt;this&lt;/span&gt;.valueAccess.Key, valueAccessFailureMessage }), currentTarget, key);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;else&lt;/span&gt; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;//custom validation logic between prop1 and prop2&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (!objectToValidate.StartsWith((&lt;span style="color: blue"&gt;string&lt;/span&gt;)myProp1)) { &lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;base&lt;/span&gt;.LogValidationResult(validationResults, &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: teal"&gt;CultureInfo&lt;/span&gt;.CurrentUICulture, &lt;span style="color: blue"&gt;this&lt;/span&gt;.MessageTemplate, &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;object&lt;/span&gt;[] { objectToValidate, myProp1 }), currentTarget, key);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; DefaultMessageTemplate {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: teal"&gt;Resources&lt;/span&gt;.MyProp2ValidatorDefaultMessageTemplate; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;What’s left is to provide the ValueAccess to the validator’s constructor. This is done in the MyProp2ValidatorAttribute class, if using attributes to place validators, or in the MyProp2ValidatorData if using configuration files. MyProp2ValidatorAttribute would look like this:  &lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 public\cf0  \cf2 class\cf0  \cf10 MyProp2ValidatorAttribute\cf0  : \cf10 ValueValidatorAttribute\par ??\cf0 \{\par ??    \cf2 protected\cf0  \cf2 override\cf0  \cf10 Validator\cf0  DoCreateValidator(\cf10 Type\cf0  targetType)\par ??    \{\par ??        \cf2 throw\cf0  \cf2 new\cf0  \cf10 InvalidOperationException\cf0 (\cf13 "se debe crear con con value access builder"\cf0 );\par ??    \}\par ??\par ??    \cf2 protected\cf0  \cf2 override\cf0  \cf10 Validator\cf0  DoCreateValidator(\cf10 Type\cf0  targetType, \cf10 Type\cf0  ownerType, \cf10 MemberValueAccessBuilder\cf0  memberValueAccessBuilder)\par ??    \{\par ??        \cf10 PropertyInfo\cf0  propertyInfo = ownerType.GetProperty(\cf10 MyProp2Validator\cf0 .OtherPropName);\par ??        \cf2 if\cf0  (propertyInfo == \cf2 null\cf0 )\par ??        \{\par ??            \cf2 throw\cf0  \cf2 new\cf0  \cf10 InvalidOperationException\cf0 (\cf10 String\cf0 .Format(\cf10 Resources\cf0 .MyProp2ValidatorAttributeCouldNotFindProperty, \cf2 new\cf0  \cf2 string\cf0 [] \{ ownerType.Name, \cf10 MyProp2Validator\cf0 .OtherPropName \}));\par ??        \}\par ??        \cf2 return\cf0  \cf2 new\cf0  \cf10 MyProp2Validator\cf0 (memberValueAccessBuilder.GetPropertyValueAccess(propertyInfo));\par ??    \}\par ??\}}&lt;br /&gt;--&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: teal"&gt;MyProp2ValidatorAttribute&lt;/span&gt; : &lt;span style="color: teal"&gt;ValueValidatorAttribute&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: teal"&gt;Validator&lt;/span&gt; DoCreateValidator(&lt;span style="color: teal"&gt;Type&lt;/span&gt; targetType)&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: teal"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: maroon"&gt;"A member value access builder is needed."&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: teal"&gt;Validator&lt;/span&gt; DoCreateValidator(&lt;span style="color: teal"&gt;Type&lt;/span&gt; targetType, &lt;span style="color: teal"&gt;Type&lt;/span&gt; ownerType, &lt;span style="color: teal"&gt;MemberValueAccessBuilder&lt;/span&gt; memberValueAccessBuilder)&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: teal"&gt;PropertyInfo&lt;/span&gt; propertyInfo = ownerType.GetProperty(&lt;span style="color: teal"&gt;MyProp2Validator&lt;/span&gt;.OtherPropName);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (propertyInfo == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: teal"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: teal"&gt;String&lt;/span&gt;.Format(&lt;span style="color: teal"&gt;Resources&lt;/span&gt;.MyProp2ValidatorAttributeCouldNotFindProperty, &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt;[] { ownerType.Name, &lt;span style="color: teal"&gt;MyProp2Validator&lt;/span&gt;.OtherPropName }));&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: teal"&gt;MyProp2Validator&lt;/span&gt;(memberValueAccessBuilder.GetPropertyValueAccess(propertyInfo));&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Finally, you can test the validation logic using the following code:&lt;/p&gt; &lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 private\cf0  \cf2 void\cf0  buttonValidate_Click(\cf2 object\cf0  sender, \cf10 EventArgs\cf0  e)\par ??\{\par ??    \cf10 MyEntity\cf0  ent = \cf2 new\cf0  \cf10 MyEntity\cf0 ();\par ??    ent.MyProperty1 = textBoxProp1.Text;\par ??    ent.MyProperty2 = textBoxProp2.Text;\par ??    \cf10 ValidationResults\cf0  r = \cf10 Validation\cf0 .Validate&amp;lt;\cf10 MyEntity\cf0 &amp;gt;(ent);        \par ??    \cf2 if\cf0  (!r.IsValid)\par ??    \{\par ??        DisplayValidationResults(r);\par ??    \}\par ??    \cf2 else\cf0  \{\par ??        \cf10 MessageBox\cf0 .Show(\cf13 "ok"\cf0 );\par ??    \}\par ??\}}&lt;br /&gt;--&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; buttonValidate_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: teal"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: teal"&gt;MyEntity&lt;/span&gt; ent = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: teal"&gt;MyEntity&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ent.MyProperty1 = textBoxProp1.Text;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ent.MyProperty2 = textBoxProp2.Text;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: teal"&gt;ValidationResults&lt;/span&gt; r = &lt;span style="color: teal"&gt;Validation&lt;/span&gt;.Validate&amp;lt;&lt;span style="color: teal"&gt;MyEntity&lt;/span&gt;&amp;gt;(ent);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (!r.IsValid)&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DisplayValidationResults(r);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;else&lt;/span&gt; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: teal"&gt;MessageBox&lt;/span&gt;.Show(&lt;span style="color: maroon"&gt;"ok"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;It's only left to provide the UI integration for the custom validator to assure averything's working right. I hope to be posting this in a&amp;nbsp;second part soon.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-3096229791054885153?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/3096229791054885153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=3096229791054885153&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/3096229791054885153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/3096229791054885153'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/05/developing-custom-property-comparison.html' title='Developing a Custom Property Comparison Validator using Entlib&amp;#39;s VAP'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-4205695331175388246</id><published>2007-04-16T12:27:00.000-03:00</published><updated>2007-04-16T12:32:07.600-03:00</updated><title type='text'>Workflow Foundation conference's material</title><content type='html'>The material (powerpoint presentation and code samples) of the &lt;a href="http://solepano.blogspot.com/2007/03/sign-up-in-wfs-conference-ms-argentina.html"&gt;Introduction To Workflow Foundation&lt;/a&gt; conference is now available for &lt;a href="http://turing.lagash.com/download/IntroductionToWF.zip"&gt;download&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-4205695331175388246?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/4205695331175388246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=4205695331175388246&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4205695331175388246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4205695331175388246'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/04/workflow-foundation-conferences.html' title='Workflow Foundation conference&apos;s material'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-5675655679589513130</id><published>2007-03-20T13:03:00.000-03:00</published><updated>2007-03-20T13:33:38.907-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WF'/><title type='text'>Sign up in the WF's conference @ MS Argentina</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;On Thursday the 12&lt;sup&gt;th&lt;/sup&gt; (from 9 am to 1 pm) I will take part in the “&lt;span style="font-weight: bold;"&gt;Introduction to Windows Workflow Foundation&lt;/span&gt;” conference given at Microsoft &lt;st1:place st="on"&gt;&lt;st1:country-region st="on"&gt;Argentina&lt;/st1:country-region&gt;&lt;/st1:place&gt;, along with Diego Gonzalez (MVP) and Jorge Fioranelli.  &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;Here is the conference abstract:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;“&lt;span style="font-style: italic;"&gt;Between the new technologies included in the recently released .Net Framework 3.0, we found Windows Workflow Foundation, which consists on the most innovating tool set included in this new framework’s version. The possibility of extracting the workflow concept from the applications as a reusable and extensible element is an extremely innovating aspect in terms of application design. Tools are also included that let you visually edit workflows, enabling analysts and users without programming knowledge to extend applications with a minimum impact in the whole application.&lt;/span&gt;&lt;o:p style="font-style: italic;"&gt;&lt;br /&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style="font-style: italic;"&gt;The conference will consist on an introduction to the technology, showing its main characteristics, a demonstration of its more relevant advanced aspects, and will end with two examples of real projects where Windows Workflow Foundation has been used in combination with other technologies to solve common issues.&lt;/span&gt;”&lt;o:p&gt;&lt;br /&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;You can see the details and &lt;span style="font-weight: bold;"&gt;sign up&lt;/span&gt; &lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032334436&amp;amp;Culture=es-AR"&gt;here&lt;/a&gt;. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;See you there!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-5675655679589513130?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/5675655679589513130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=5675655679589513130&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/5675655679589513130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/5675655679589513130'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/03/sign-up-in-wfs-conference-ms-argentina.html' title='Sign up in the WF&apos;s conference @ MS Argentina'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-3836248444724168325</id><published>2007-03-17T19:31:00.000-03:00</published><updated>2007-05-16T14:53:13.491-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entlib'/><title type='text'>Environmental Overrides</title><content type='html'>&lt;a href="http://www.codeplex.com/entlib/Release/ProjectReleases.aspx?ReleaseId=2081"&gt;February 2007 CTP of Enterprise Library 3.0&lt;/a&gt; includes a very cool feature called "Environmental Overrides". This feature provides the capability of defining different environments in your application's configuration, and overriding some of the configuration settings in these environments. This is very useful in common scenarios, such as having different connection strings in development, testing and production. For a more detail explanation of how this works, read &lt;a href="http://bloggingabout.net/blogs/olaf/archive/2007/02/18/environmental-overrides-made-it-into-entlib-v3.aspx"&gt;here&lt;/a&gt;, directly from its creator.&lt;br /&gt;&lt;br /&gt;The tool sounded very promising to me, but pitifully, I couldn't make it work. I found the following two issues:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;When I generate the merged file for one environment (by clicking the "Save merged configuration" item of its context menu), the resulting file do not have the property's value overridden. This is an important problem for me, since it prevents the whole override feature to work. I reported this in more detail &lt;a href="http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=8298&amp;ANCHOR#Post27067"&gt;here&lt;/a&gt;, but the P&amp;amp;P people couldn't reproduce the bug.&lt;/li&gt;&lt;li&gt;After reopening the app.config file, and loading one delta file for an environment,  the settings for my overridden properties do not appear as expected. I see the "&lt;span id="ctl00_ctl00_ctl00_Content_ProjectBaseMain_ProjectMain_PostRepeater_ctl00_BodyLabel"&gt;Don't Override Properties" option instead. &lt;/span&gt;I have also reported this with no luck &lt;a href="http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=8299&amp;amp;ANCHOR#Post27069"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Is anyone having the same problem? Did anyone make it work?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-3836248444724168325?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/3836248444724168325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=3836248444724168325&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/3836248444724168325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/3836248444724168325'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/03/environmental-overrides.html' title='Environmental Overrides'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-4660430521923225610</id><published>2007-03-12T14:45:00.000-03:00</published><updated>2008-12-10T22:59:21.899-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net 3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>How-To: Implement a WCF Authorization Manager Using AzMan</title><content type='html'>This article intends to explain how to use &lt;a href="http://msdn.microsoft.com/msdnmag/issues/03/11/AuthorizationManager"&gt;AzMan&lt;/a&gt;  to implement a custom authorization policy in WCF.  &lt;p&gt;&lt;strong&gt;AzMan&lt;/strong&gt; (Windows Authorizacion Manager) is a role-based  application framework which provides runtime access validation methods, storage,  and a UI to manage access control. The Authorization Manager runtime is  separated from the authorization policy store, which may be stored in Active  Directory, ADAM, or XML. AzMan is composed of two parts:&lt;/p&gt; &lt;ol&gt;&lt;li&gt;&lt;b&gt;Runtime&lt;/b&gt;: Provided by AZROLES.DLL, exposes a set of COM interfaces  used by applications that employ role-based security.  &lt;/li&gt;&lt;li&gt;&lt;b&gt;Administration UI&lt;/b&gt;: MMC snap-in that you can try out by running  AZMAN.MSC or by adding the Authorization Manager snap-in to your MMC console of  choice:&lt;/li&gt;&lt;/ol&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_vRmmMCC9gL0/RfWT0aijg1I/AAAAAAAAAAs/j5uC4gYn9jc/s1600-h/azManConsole.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_vRmmMCC9gL0/RfWT0aijg1I/AAAAAAAAAAs/j5uC4gYn9jc/s320/azManConsole.JPG" alt="" id="BLOGGER_PHOTO_ID_5041097886597874514" border="0" /&gt;&lt;/a&gt; &lt;p&gt;&lt;console_picture&gt;&lt;/console_picture&gt;&lt;/p&gt; &lt;p&gt;Follow these steps to use AzMan from within a custom authorization policy in  your WCF Service:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. Put AzMan to work with ADAM as the authorization policy  store.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;As I said before, the authorization policy store is independent from the  authorization runtime. In this example I used ADAM as the policy store, but you  can use an xml file as well.  &lt;/p&gt;&lt;blockquote&gt; &lt;p&gt;1.1. Download and Install AzMan: AzMan comes with Windows Server 2003. For othe versions of windows, the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=e487f885-f0c7-436a-a392-25793a25bad7&amp;displaylang=en"&gt;Windows  Server 2003 SP1 Administration ToolPack&lt;/a&gt; can be installed.&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;1.2. Download &lt;a href="http://www.microsoft.com/windowsserver2003/adam/default.mspx"&gt;ADAM&lt;/a&gt; and  create a new ADAM Instance (not available for Windows Vista)&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_vRmmMCC9gL0/RfWT9qijg2I/AAAAAAAAAA0/QsPwsUB3Pyk/s1600-h/adamInstall.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_vRmmMCC9gL0/RfWT9qijg2I/AAAAAAAAAA0/QsPwsUB3Pyk/s320/adamInstall.JPG" alt="" id="BLOGGER_PHOTO_ID_5041098045511664482" border="0" /&gt;&lt;/a&gt;  &lt;/p&gt;&lt;p&gt;1.3 Configure AzMan to use ADAM as the policy store&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt; Steps 1.2 and 1.3 are explained in detail in steps 1 and 2 of &lt;a href="http://msdn2.microsoft.com/en-us/library/ms998331.aspx"&gt;this article&lt;/a&gt;,  so you can follow the from there.&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;The ADAM instance can be administrated from the Adam ADSI Edit  tool:&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_vRmmMCC9gL0/RfWUCqijg3I/AAAAAAAAAA8/R72Kn8D9J14/s1600-h/adamEdit.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_vRmmMCC9gL0/RfWUCqijg3I/AAAAAAAAAA8/R72Kn8D9J14/s320/adamEdit.JPG" alt="" id="BLOGGER_PHOTO_ID_5041098131411010418" border="0" /&gt;&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;/blockquote&gt; &lt;p&gt;&lt;strong&gt;2. Ask for the user's permissions programmatically.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Once you have your role-based policy created in AzMan, is time to know how to  ask for permissions programmatically.  &lt;/p&gt;&lt;blockquote&gt; &lt;p&gt;2.1 In your .Net project add a reference to the  &lt;strong&gt;Microsoft.Interop.Security.AzRoles&lt;/strong&gt; assembly (found at %AzMan  Download Dir%\Windows(R) 2000 Authorization Manager Runtime\PIA\1.2).  &lt;/p&gt;&lt;p&gt;2.2 In order to connect to your AzMan application you can use the following  lines of code:&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote  style="color: rgb(0, 0, 153);font-family:courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;AzAuthorizationStore store = new AzAuthorizationStore();&lt;br /&gt;store.Initialize(0, ConfigurationManager.AppSettings["azManStore"], null);&lt;br /&gt;IAzManApplication app = store.OpenApplication(&lt;br /&gt;  ConfigurationManager.AppSettings["azManAppName"],  null);&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;The &lt;em&gt;azManStore&lt;/em&gt; configuration entry is of the form:  &lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;"msldap://localhost:389/CN=AzManADAMStore,OU=SecNetPartition,O=SecNet,C=AR"&lt;/span&gt;&lt;/span&gt;  for an ADAM repository, or&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;"msxml://c:/TestAuthStore.xml"&lt;/span&gt;&lt;/span&gt; for an xml file repository&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;2.3 To ask if a user has access to a given operation you need to istantiate  an &lt;strong&gt;IAzClientContext&lt;/strong&gt; from the user identity and then ask the  context whether it has access to a given operation.&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;To obtain the client context from his user name:&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote  style="color: rgb(0, 0, 153);font-family:courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;IAzClientContext ctx = app.InitializeClientContextFromName(user, domain,  null);&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;To obtain it from a  System.Security.Principal.WindowsIdentity:&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote  style="color: rgb(0, 0, 153);font-family:courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;HandleRef handle = new HandleRef(this, identity.Token);&lt;br /&gt;IAzClientContext ctx =  app.InitializeClientContextFromToken(  &lt;br /&gt;      (UInt64)handle.Handle, 0);&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;To ask for access to a given operation:  &lt;/p&gt;&lt;p  style="color: rgb(0, 0, 153);font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;object[] operations = { (object)operationId };&lt;br /&gt;object[] scopes = { (object)"" };&lt;br /&gt;object[] results = (object[])context.AccessCheck(app.Name, (object)scopes,    (object)operations, null, null, null, null, null);&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote style="font-family: courier new;"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new;"&gt; &lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;If the result is 0 the access is granted.&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;Note that the query is made for the operation id, as it was entered in the  AzMan operation definition. Usually you'll need a mapping between the operations  ids and some friendly name.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;br /&gt;&lt;strong&gt;3. Implement your a WCF custom Authorization Manager that relies  on AzMan for authorization.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Now we have code access to AzMan to query for authorization, we want to  integrate that to our WCF Service. We will implement a custom   authorizationManager for that, since is the WCF natural extensibility point for  authorization (although you can do it in a custom behavior also, the  AuthorizationManager would be more accurate).&lt;/p&gt; &lt;p&gt;The custom AuthorizationManager must derive from  System.ServiceModel.ServiceAuthorizationManager and override the  &lt;b&gt;CheckAccessCore&lt;/b&gt; method. For more information see &lt;a href="http://msdn2.microsoft.com/en-us/library/ms731774.aspx"&gt;How To: Create a  Custom AuthorizationManager for a Service&lt;/a&gt;   &lt;/p&gt;&lt;p&gt;In this example we will obtain the required action and the username from the  operationContext and then use our AzMan utility class (AthorizationRepository)  to ask whether the user has access to the given operation.  &lt;/p&gt;&lt;p  style="color: rgb(0, 0, 153);font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;class MyAuthorizationManager : ServiceAuthorizationManager {  &lt;/span&gt;&lt;/p&gt;&lt;blockquote  style="color: rgb(0, 0, 153);font-family:courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;protected override bool CheckAccessCore(OperationContext operationContext) {&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote  style="color: rgb(0, 0, 153);font-family:courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;   //Instanciate our AzMan utility class&lt;br /&gt;  AuthorizationRepository azMan = new  AuthorizationRepository();&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote  style="color: rgb(0, 0, 153);font-family:courier new;"&gt; &lt;/blockquote&gt; &lt;blockquote  style="color: rgb(0, 0, 153);font-family:courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;   //Obtain the requested action from the context&lt;br /&gt;  string action =        operationContext.RequestContext.RequestMessage.Headers.Action;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote face="courier new" style="color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote face="courier new" style="color: rgb(0, 0, 153);"&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;   // Iterate through the various claimsets in the authorization context      // to obtain the user name&lt;br /&gt;  foreach (ClaimSet cs in   operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)  {&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;      foreach (Claim c in cs.FindClaims(ClaimTypes.Name,          &lt;br /&gt;             Rights.PossessProperty))  {&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;p style="color: rgb(0, 0, 153);"&gt;&lt;span style="font-size:85%;"&gt;         string userName =  c.Resource.ToString();&lt;br /&gt;        //check access&lt;br /&gt;        if (azMan.HasAccess(userName, action))   {&lt;br /&gt;             return true;&lt;br /&gt;        }&lt;br /&gt;           }&lt;br /&gt;  }&lt;br /&gt;  return false;&lt;br /&gt;}&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;  &lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt; &lt;blockquote style="font-family: courier new; color: rgb(0, 0, 153);"&gt; &lt;/blockquote&gt;   &lt;p&gt;Hope it result useful!&lt;br /&gt;&lt;/p&gt; &lt;p style="font-weight: bold;"&gt;Some links:&lt;/p&gt; &lt;p&gt; &lt;strong&gt;AzMan&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetserv/html/AzManApps.asp"&gt;Developing  Applications Using Windows Authorization Manager&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/03/11/AuthorizationManager"&gt;&lt;br /&gt;Use  Role-Based Security in Your Middle Tier .NET Apps with Authorization Manager&lt;/a&gt;   &lt;/p&gt;&lt;p&gt;&lt;strong&gt;ADAM&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/windowsserver2003/adam/default.mspx"&gt;Windows  Server 2003 Active Directory Application Mode&lt;/a&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms998331.aspx"&gt;&lt;br /&gt;How To: Use  ADAM for Roles in ASP.NET 2.0&lt;/a&gt;  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;WCF Authorization&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms731774.aspx"&gt;How To:  Create a Custom AuthorizationManager for a Service (WCF)&lt;/a&gt;&lt;a href="http://www2.codebetter.com/blogs/sam.gentile/archive/2006/05/26/145540.aspx"&gt;&lt;br /&gt;How  To: STS/Windows Authentication with ADAM/AD, Roles in AzMan with WCF&lt;/a&gt; (using  WCF behaviours)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-4660430521923225610?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/4660430521923225610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=4660430521923225610&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4660430521923225610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/4660430521923225610'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/03/how-to-implement-wcf-authorization.html' title='How-To: Implement a WCF Authorization Manager Using AzMan'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_vRmmMCC9gL0/RfWT0aijg1I/AAAAAAAAAAs/j5uC4gYn9jc/s72-c/azManConsole.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-1736985394534523611</id><published>2007-03-11T10:34:00.000-03:00</published><updated>2007-03-12T15:15:06.645-03:00</updated><title type='text'>Documentation Generation in .Net 2.0</title><content type='html'>I found out that generating chm documentation from xml code comments in .Net 2.0 is not as easy as it was before. Thing is that &lt;a href="http://ndoc.sourceforge.net/"&gt;NDoc &lt;/a&gt;has not been upgraded. Although it is available an &lt;a href="http://www.kynosarges.de/NDoc.html"&gt;NDoc2.0 alpha version&lt;/a&gt;, the product does not seem to be maintained.&lt;br /&gt;&lt;br /&gt;Apparently, this is due to the throw of &lt;a href="http://www.sandcastledocs.com"&gt;Sandcastle&lt;/a&gt;, the Microsoft's official documentation compiler (which is also included in Visual Studio's SDK Feb 2007). Though the documentation generation using this tool involves several steps, some of its users have already published &lt;a href="http://www.sandcastledocs.com/Wiki%20Pages/Scripts%20and%20Automation%20from%20Community.aspx"&gt;scripts and tools&lt;/a&gt; that automate this task.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-1736985394534523611?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/1736985394534523611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=1736985394534523611&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/1736985394534523611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/1736985394534523611'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/03/documentation-generation-on-net-20.html' title='Documentation Generation in .Net 2.0'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-5937118682178972857</id><published>2007-01-22T18:08:00.001-03:00</published><updated>2007-01-22T18:10:55.574-03:00</updated><title type='text'>Reflector's addins</title><content type='html'>&lt;p&gt;&lt;/p&gt; &lt;p&gt;  &lt;/p&gt;&lt;p&gt;I've been told of two addins for this great tool &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;One is the &lt;a href="http://www.denisbauer.com/NETTools/FileDisassembler.aspx"&gt;File Disassembler&lt;/a&gt; addin, which you can use to generate code, in any language, from any assembly. This maybe useful for translating from one language to another, or to view the code in Visual Studio rather than in Reflector, but the truth is I haven't got the opportunity to need it yet. &lt;/p&gt;   &lt;p&gt;The other addin, which I do use a lot, is the &lt;a href="http://blog.dotnetwiki.org/ReflectorCodeMetricsAddinForReflector.aspx"&gt;Code Metrics Addin&lt;/a&gt;. This one computes several code quality metrics of the assembly, such as the number of members of a class, the cyclomatic complexity, or the distance to the main sequence.&lt;/p&gt;&lt;p&gt; Since the link for downloading seems to be broken, I've upload it &lt;a href="http://web.fi.uba.ar/%7Espano/Peli%27s%20Reflector%20Addins_4_2_11_0.zip"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-5937118682178972857?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/5937118682178972857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=5937118682178972857&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/5937118682178972857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/5937118682178972857'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/01/reflector-addins.html' title='Reflector&amp;#39;s addins'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-6022401764416735848</id><published>2007-01-22T17:35:00.001-03:00</published><updated>2007-01-22T17:45:39.044-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogs'/><title type='text'>Blogging tools</title><content type='html'>&lt;p&gt;I've recently discover two handy tools for blogging. The first one is the &lt;a href="http://ideas.live.com/programpage.aspx?versionId=4372c8c2-b76f-4d44-aea1-9835b61d8dc1"&gt;Windows Live Writer&lt;/a&gt;. It is a little more friendly than the Blogger's editor, besides the advantage of allowing you to write offline. I have no problems in writing here to Blogger, despite of not being able to upload images.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;The other tool I started using last week is the &lt;a href="http://www.google.com/reader"&gt;Google Reader&lt;/a&gt;. It is really cool, like all other google stuff. It has the drawback of you having to request the page, but you can access it from any computer.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-6022401764416735848?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/6022401764416735848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=6022401764416735848&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/6022401764416735848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/6022401764416735848'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/01/blogging-tools.html' title='Blogging tools'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-1145097644576060179</id><published>2007-01-22T14:02:00.001-03:00</published><updated>2008-12-10T22:59:22.141-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net 3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='WF'/><title type='text'>More on WF: Getting Started</title><content type='html'>Continuing with the research on Workflow Foundation, here goes just a couple of things to get started with. &lt;p&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;u&gt;1- Quickly create your first sequence workflow&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;[See &lt;a href="http://solepano.blogspot.com/2006/07/starting-developing-in-net-framework.html"&gt;my previous post&lt;/a&gt; about the requirements for developing .Net framework 3 features.]  &lt;/p&gt;&lt;p&gt;I am not going to put many details here, but to create your first workflow you need to select one of the workflow project templates in Visual Studio 2005. Just to start select the &lt;strong&gt;Sequential Workflow Console Application&lt;/strong&gt; template. This generates a project with the references to the WF assemblies, the workflow itself and a test program.  &lt;/p&gt;&lt;p&gt;By clicking on the workflow class the workflow is shown in the designer. Here is where you can drag activities from the toolbox. For example drag a &lt;strong&gt;CodeActivity&lt;/strong&gt;. In the CodeActivity &lt;strong&gt;ExecuteCode&lt;/strong&gt; property, type a method's name and press enter. VS will generate the method stub for you. Just write hello world to console there. Pressing the "view code" tab, the partial class with the workflow code (wfl properties, event_handlers, methods, etc) appears. You can see that the workflow inherits from &lt;strong&gt;SequentialWorkflowActivity&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_vRmmMCC9gL0/RbTujbdiU3I/AAAAAAAAAAM/et_dyac7Dlk/s1600-h/wfConsoleApp.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_vRmmMCC9gL0/RbTujbdiU3I/AAAAAAAAAAM/et_dyac7Dlk/s320/wfConsoleApp.JPG" alt="" id="BLOGGER_PHOTO_ID_5022901776859419506" border="0" /&gt;&lt;/a&gt;  &lt;/p&gt;&lt;p&gt;  &lt;/p&gt;&lt;p&gt;So far we have the workflow defined with a set of activities. What we need now is to host the workflow and execute it. The generated program shows us how to do it:  &lt;/p&gt;&lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;color:#0000a0;"&gt;using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) {&lt;/span&gt;  &lt;/p&gt;&lt;blockquote style="font-family: courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;color:#0000a0;"&gt;...&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote style="font-family: courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;color:#0000a0;"&gt;WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1));&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote style="font-family: courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;color:#0000a0;"&gt;instance.Start();&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote style="font-family: courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;color:#0000a0;"&gt;...&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;color:#0000a0;"&gt;}&lt;/span&gt;  &lt;/p&gt;&lt;p&gt; &lt;/p&gt; &lt;p&gt;So, just press F5 and see the greeting message!&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;u&gt;2- Get a feel of the Pre-build Activities&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Some of the pre-build activities I have been experiencing with:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;CallExternalMethod  &lt;/li&gt;&lt;li&gt;Code  &lt;/li&gt;&lt;li&gt;Delay  &lt;/li&gt;&lt;li&gt;IfElse  &lt;/li&gt;&lt;li&gt;Listen  &lt;/li&gt;&lt;li&gt;Sequence  &lt;/li&gt;&lt;li&gt;HandleExternalEvent&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;They are more or less self explained...I only want to mention one thing that may be a constraint in some circumstances: &lt;/p&gt; &lt;p&gt;The CallExternalMethod activity needs the following properties to execute:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;InterfaceType  &lt;/li&gt;&lt;li&gt;MethodName  &lt;/li&gt;&lt;li&gt;Parameters&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;and the HandleExternalEvent similar properties:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;InterfaceType  &lt;/li&gt;&lt;li&gt;EventName  &lt;/li&gt;&lt;li&gt;Parameters&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In both cases the InterfaceType must be an Interface decorated with the &lt;strong&gt;ExternalDataExchange&lt;/strong&gt; attribute, only this type of interfaces will be listed by the object browser. So the presence of that attribute is what I think may be a restriction as you can't use just any already built assembly.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;u&gt;&lt;strong&gt;3- Pass data to the WF:&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt; &lt;p&gt;   &lt;/p&gt;&lt;p&gt;There are two general approaches for receiving data into a workflow when it is started. They are Parameters and Events. With parameters, a list of parameter names and types are defined with the workflow. These parameter values are passed in by a host when it starts a new instance of the workflow type. With events, workflow authors add an activity that receives an event and data associated with the event. Events are generally specific to the host and custom activities that have been designed to handle the event.  &lt;/p&gt;&lt;p&gt;   &lt;/p&gt;&lt;p&gt;The parameters can be passed in the CreateWorkflow method as shown here:  &lt;/p&gt;&lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;color:#004080;"&gt;using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) {&lt;/span&gt;  &lt;/p&gt;&lt;blockquote style="font-family: courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;color:#004080;"&gt;...&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote style="font-family: courier new;"&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;color:#004080;"&gt;Dictionary&amp;lt;string, object&amp;gt; parameters = new Dictionary&amp;lt;string, object&amp;gt;();&lt;br /&gt;parameters.Add("FirstName", "Tom");&lt;br /&gt;parameters.Add("LastName", "Sawyer"); &lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;color:#004080;"&gt;WorkflowInstance instance = wr.CreateWorkflow(typeof(HelloWorldWorkflow.Workflow1), parameters);&lt;br /&gt;instance.Start();&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;  &lt;blockquote style="font-family: courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;color:#004080;"&gt;...&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;color:#004080;"&gt;}&lt;/span&gt;  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;4- Make use of Conditions&lt;/u&gt;&lt;/strong&gt;  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;   &lt;/p&gt;&lt;p&gt;A rule condition is a condition statement that is created in a dialog and stored as XML with the workflow. It can include predicates that compare workflow state and Boolean algebra combining multiple predicates. The conditions can be used in various activities including IfElse, While, ConditionedActivityGroup, and Replicator.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Take for example the IfElse activity. A condition can be set to one or both of its branches using the activity's properties. You can specify a CodeCondition or a DeclarativeCondition. In the first case you just enter the method's name. When you press enter the condition handler will be generated and shown in the code window. Put your logic in there, for instance:&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;color:#000080;"&gt;public void If_Condition(object sender, ConditionalEventArgs e){&lt;/span&gt;&lt;/p&gt; &lt;blockquote style="font-family: courier new;"&gt; &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;strong&gt;e.Result &lt;/strong&gt;= this.reviewArgs.Review.Approved;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;color:#000080;"&gt;}&lt;/span&gt;  &lt;/p&gt;&lt;p&gt;  &lt;/p&gt;&lt;p&gt;When using the DeclarativeCondition, you can use the Condition Editor to create it. You can access the workflow properties by intellisense.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_vRmmMCC9gL0/RbTu2rdiU4I/AAAAAAAAAAU/H21DEazt3_g/s1600-h/rule+editor.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_vRmmMCC9gL0/RbTu2rdiU4I/AAAAAAAAAAU/H21DEazt3_g/s320/rule+editor.JPG" alt="" id="BLOGGER_PHOTO_ID_5022902107571901314" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-1145097644576060179?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/1145097644576060179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=1145097644576060179&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/1145097644576060179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/1145097644576060179'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/01/more-on-wf-getting-started.html' title='More on WF: Getting Started'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_vRmmMCC9gL0/RbTujbdiU3I/AAAAAAAAAAM/et_dyac7Dlk/s72-c/wfConsoleApp.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-7062696610093981444</id><published>2007-01-16T14:24:00.000-03:00</published><updated>2007-01-16T14:56:22.834-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogs'/><title type='text'>My turn in the blog-tag game!</title><content type='html'>&lt;p&gt;As I’ve been tagged by &lt;a href="http://adrianalonso.blogspot.com/"&gt;my boyfriend&lt;/a&gt;, I suppose it’s my turn in this blogger’s game to play. So, here goes 5 things some people may don’t know about me:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;I went to live on my own a few months ago, to a very cute apartment in Almagro, 5 blocks from my parents. It can’t actually be said a live “alone” since I have this eternal, and of course very welcome and lovely visit, my boyfriend.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I have a degree in Electronic Engineer from the University of Buenos Aires, but I’ve never worked as such. I have always worked as a software developer, nowadays in a great software company: &lt;a href="http://www.lagash.com"&gt;Lagash Systems&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I have always like Maths. I kind of have it in the blood since both my parents are mathematicians. I’ve always teach math, first giving particular lessons and since many years now at the university, where I still teach “Algebra II” and used to teach “Probability and Statistics” too.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;When I was young I studied music for many years (since I was 6 till 15) at the National Conservatory. I played piano and flout. Unfortunately I have a very bad memory and can’t remember a single piece of music. But I can still play if I’m in front of the sheet. I play mostly classic, despite for some Queen songs I learned when I was a teen and a great fan of them.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In my free time? I like to walk, dance, and go biking a lot. I try to go by feet everywhere whenever it is possible. I don’t like to stay much inside, I prefer to take some air. I really enjoy going anywhere with my boyfriend, going to the country house on Sundays with the family and hanging out with my friends.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Now it's time to tag another 5 people: &lt;a href="http://weblogs.shockbyte.com.ar/rodolfof/"&gt;RodolfoF&lt;/a&gt;, &lt;a href="http://zPod.com.ar"&gt;Zaiden&lt;/a&gt;, &lt;a href="http://weblogs.asp.net/cibrax/"&gt;PabloC&lt;/a&gt; , &lt;a href="http://catalizadoranomore.blogspot.com/"&gt;Cyn&lt;/a&gt; and &lt;a href="http://catalizadoranomore.blogspot.com/"&gt;Pede&lt;/a&gt;. &lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-7062696610093981444?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/7062696610093981444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=7062696610093981444&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/7062696610093981444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/7062696610093981444'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2007/01/my-turn-in-blog-tag-game.html' title='My turn in the blog-tag game!'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-116534303780462671</id><published>2006-12-05T14:49:00.000-03:00</published><updated>2007-02-15T16:21:16.006-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net 3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='WF'/><title type='text'>First steps in Workflow Foundation</title><content type='html'>&lt;p   style="margin: 0in;font-family:verdana;font-size:10pt;" lang="EN-US"&gt;&lt;span style="font-size:85%;"&gt;I have started to play with &lt;a href="http://wf.netfx3.com/"&gt;Windows Workflow Foundation (WF)&lt;/a&gt; a few days ago. So far it seems very interesting, shipping with handy pre-build activities, persistence and tracking services, prity designers for visual studio, the capability of hosting these designers anywhere else…web services interaction, etc. Promising.&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin: 0in;font-family:verdana;font-size:10pt;" lang="EN-US"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin: 0in;font-family:verdana;font-size:10pt;" lang="EN-US"&gt;&lt;span style="font-size:85%;"&gt;I just want to take down some notes here so I don't forget what I've learned.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p  style="margin: 0in;font-size:10pt;" lang="EN-US"&gt;&lt;span style="font-weight: bold;"&gt;Some Material&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=2e575633-e357-4ee7-aaff-34138f00e830&amp;displaylang=en"&gt;MS E-Learning course&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=2e575633-e357-4ee7-aaff-34138f00e830&amp;amp;displaylang=en"&gt;Hands on Lab&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms735967.aspx"&gt;WF Documentation&lt;/a&gt; (Programming model, samples, tools)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Some Concepts&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Windows Workflow Foundation (WF)&lt;/span&gt;: Set of components, tools, and a designer that developers can use to create and implement workflows in .NET Framework applications. It is part of the Microsoft .NET Framework version 3.0.&lt;/li&gt;&lt;li&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-weight: bold;"&gt;Workflow&lt;/span&gt;: a set of activities that are stored as a model that describes a real-world process. &lt;/span&gt;&lt;span  lang="EN-US" style="font-family:Arial;"&gt;A workflow is designed by laying out activities&lt;/span&gt;&lt;span lang="ES"&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-weight: bold;"&gt;Activity&lt;/span&gt;: &lt;/span&gt;&lt;span  lang="EN-US" style="font-family:Arial;"&gt;A step in a workflow. The unit of execution, re-use and composition for a workflow.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Types of workflows (&lt;a href="http://blogs.msdn.com/davegreen/archive/2005/10/20/483309.aspx"&gt;Here&lt;/a&gt; is a post about how to decide which type to use):&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Sequential&lt;/span&gt;: &lt;span style="color:black;"&gt;Consists of activities that execute in a predefined order. Has a clear direction of flow from top to bottom, although it can include loops, conditional tests, and other flow-control structures.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;State-Machine&lt;/span&gt;: Consists of states and transitions that change a workflow instance from one state to another. Although there is an initial state and a final state, the states have no fixed order, and an instance can move through the workflow in one of many paths.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Data-Driven&lt;/span&gt;: I&lt;span style="color:black;"&gt;s usually a sequential workflow that contains constrained activity groups and policies. In a data-driven or rules-based workflow, rules that check external data determine the path of a workflow instance. The constrained activities check rules to determine the activities that can occur.&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;  &lt;p style="margin: 0in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;    &lt;p style="margin: 0in; font-size: 10pt; text-align: center;" lang="EN-US"&gt; &lt;/p&gt;    &lt;p style="margin: 0in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;    &lt;p style="margin: 0in; font-size: 10pt;" lang="DA"&gt; &lt;/p&gt;    &lt;p style="margin: 0in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;    &lt;p style="margin: 0in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;    &lt;p style="margin: 0in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;    &lt;p style="margin: 0in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;  &lt;p style="margin: 0in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;    &lt;p style="margin: 0in; font-size: 10pt; font-weight: bold;" lang="EN-US"&gt; &lt;/p&gt;&lt;span style="font-weight: bold;"&gt;The framework component model&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The WF framework consists on 3 assemblies, containing the following namespaces:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;System.Workflow.Activities&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;Activities&lt;/span&gt;: Defines activities that can be added to workflows to create and run an executable representation of a work process.&lt;/li&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;Activities.Configuration&lt;/span&gt;: Provides classes that represent sections of the configuration file.&lt;/li&gt;&lt;li&gt;System.Workflow.Activities.&lt;span style="font-weight: bold;"&gt;Rules&lt;/span&gt;: Contains a set of classes that define the conditions and actions that form a rule.&lt;/li&gt;&lt;li&gt;System.Workflow.Activities.&lt;span style="font-weight: bold;"&gt;Rules.Design&lt;/span&gt;: Contains a set of classes that manage the &lt;span style="font-weight: bold;"&gt;Rule Set Editor&lt;/span&gt; and the &lt;span style="font-weight: bold;"&gt;Rule Condition Editor&lt;/span&gt; dialog boxes.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;System.Workflow.ComponentModel&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;ComponentModel&lt;/span&gt;: Provides the base classes, interfaces, and core modeling constructs that are used to create activities and workflows.&lt;/li&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;ComponentModel.Compiler&lt;/span&gt;: Provides infrastructure for validating and compiling activities and workflows.&lt;/li&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;ComponentModel.Design&lt;/span&gt;: Contains classes that developers can use to build custom design-time behavior for workflows and activities and user interfaces for configuring workflows and activities at design time. The design-time environment provides systems that enable developers to arrange workflows and activities and configure their properties. The classes and interfaces defined within this namespace can be used to build design-time behavior for activities and workflows, access design-time services, and implement customized design-time configuration interfaces. It includes the TypeBrowserEditor, a cool feature that can be &lt;a href="http://www.clariusconsulting.net/blogs/kzu/archive/2006/1/7.aspx"&gt;reused&lt;/a&gt;. &lt;/li&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;ComponentModel.Serialization&lt;/span&gt;: Provides the infrastructure for managing the serialization of activities and workflows to and from extensible Application Markup Language (XAML) and CodeDOM.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p size="10pt" style="margin: 0in 0in 0in 1in;" lang="EN-US"&gt; &lt;/p&gt;            &lt;p size="10pt" style="margin: 0in 0in 0in 1in;" lang="EN-US"&gt; &lt;/p&gt;  &lt;p style="margin: 0in 0in 0in 1in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;  &lt;p style="margin: 0in 0in 0in 1in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;&lt;ul&gt;&lt;li style="font-weight: bold;"&gt;System.Workflow.Runtime&lt;/li&gt;&lt;ul&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;Runtime&lt;/span&gt;: Classes and interfaces that control the workflow &lt;span style="font-weight: bold;"&gt;runtime engine &lt;/span&gt;and the execution of a workflow instance.&lt;/li&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;Runtime.Configuration&lt;/span&gt;: Classes for configuring the workflow runtime engine.&lt;/li&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;Runtime.DebugEngine&lt;/span&gt;: Classes and interfaces for use in debugging workflow instances.&lt;/li&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;Runtime.Hosting&lt;/span&gt;: Classes that are related to &lt;span style="font-weight: bold;"&gt;services &lt;/span&gt;provided to the workflow runtime engine by the host application.&lt;/li&gt;&lt;li&gt;System.Workflow.&lt;span style="font-weight: bold;"&gt;Runtime.Tracking&lt;/span&gt;: Classes and an interface related to &lt;span style="font-weight: bold;"&gt;tracking services&lt;/span&gt;. &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;      &lt;p style="margin: 0in 0in 0in 1in; font-size: 10pt;" lang="EN-US"&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-116534303780462671?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/116534303780462671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=116534303780462671&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116534303780462671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116534303780462671'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/12/first-steps-in-workflow-foundation.html' title='First steps in Workflow Foundation'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-116534094163233360</id><published>2006-12-05T13:52:00.000-03:00</published><updated>2006-12-05T19:04:12.756-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wix'/><title type='text'>Wix install sequence</title><content type='html'>I am trying to figure out the exact behavor of the install sequence in the setup, as defined in a &lt;a href="http://wix.sourceforge.net/index.html"&gt;wix &lt;/a&gt;.wxs file. The confusion comes from the presence of the InstallUISequence and the InstallExecuteSequence tags, leaving aside the fact that there are actually four tags related to the actions sequence (AdminUiSequence and AdminExecuteSequence are used in administrative installs).  As it is said in the &lt;a href="http://www.tramontana.co.hu/wix/"&gt;wix turorial&lt;/a&gt;, &lt;strong&gt;"InstallExecuteSequence&lt;/strong&gt; is always consulted by the  installer to determine the actions, &lt;strong&gt;InstallUISequence&lt;/strong&gt; is only considered when the installer runs in  full or reduced UI mode." So, if executing without user interface, the order is determined for the InstallExecuteSequence and no doubts remain. But, if executing in full or reduced UI mode, both sequences are consulted. So, what is the resulting order of execution? If an action is placed in both sequences, it is executed twice?&lt;br /&gt;&lt;br /&gt;As for the executing order, what I suppose happens is that all actions in the InstallUISequence are run first (since they gather the information required for the installation) and then those from the InstallExecuteSequence. But it is possible that some actions need to be executed before any UI dialog, so then we should place them in both sequences.&lt;br /&gt;&lt;br /&gt;If an action is placed in both sequences, they will be apparently executed twice. Al least one exception for this rule is the AppSearch action. In the &lt;a href="http://wix.sourceforge.net/manual-wix2/wix_xsd_appsearch.htm"&gt;schema reference&lt;/a&gt; it says: “AppSearch should be authored into the InstallUISequence table and InstallExecuteSequence table. The installer prevents The AppSearch action from running in the InstallExecuteSequence sequence if the action has already run in InstallUISequence sequence.” &lt;br /&gt;&lt;br /&gt;For custom actions, the &lt;a href="http://wix.sourceforge.net/manual-wix2/wix_xsd_customaction.htm"&gt;execute attribute&lt;/a&gt; can be used for preventing the double execution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-116534094163233360?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/116534094163233360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=116534094163233360&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116534094163233360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116534094163233360'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/12/wix-install-sequence.html' title='Wix install sequence'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-116293047215833789</id><published>2006-11-07T17:03:00.000-03:00</published><updated>2007-06-10T21:23:05.698-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Office add-ins'/><title type='text'>Isolating Office Extensions with the COM Shim Wizard</title><content type='html'>&lt;a href="http://msdn.microsoft.com/office/default.aspx?pull=/library/en-us/dno2k3ta/html/ODC_Office_COM_Shim_Wizards.asp#odc_office_com_shim_wizards_usingthewizardformanagedcomaddins"&gt;This article&lt;/a&gt; explains &lt;span style="" lang="EN-US"&gt;the importance of using a shim when implementing managed extensions for Office. It also provides a wizard to easily generate the shim from the managed extension. Very recommendable.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-116293047215833789?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/116293047215833789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=116293047215833789&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116293047215833789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116293047215833789'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/11/isolating-office-extensions-with-com.html' title='Isolating Office Extensions with the COM Shim Wizard'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-116292503813978641</id><published>2006-11-07T15:26:00.000-03:00</published><updated>2006-11-07T15:51:32.876-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nant'/><title type='text'>Problem with NAnt's xmlpoke task</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;There's an issue when trying to replace some part of an xml file that is under a default namespace using NAnt’s &lt;a href="http://nant.sourceforge.net/release/latest/help/tasks/xmlpoke.html"&gt;xmlpoke&lt;/a&gt; task. It happened to me the other day when trying to replace the version attribute in the following wix file:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi"&amp;gt;&lt;br /&gt;  &amp;lt;Product Name="MyProduct" Id="847A8D24-0F98-4b9f-AEA0-070ABD49F86C"   Language="1033" Codepage="1252" Version="1.0.0" Manufacturer="MyCompany"&amp;gt;&lt;br /&gt;  ......&lt;br /&gt;  &amp;lt;/Product&amp;gt;&lt;br /&gt;&amp;lt;/Wix&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Because of the namespace definition in the Wix element, calling xmlpoke simple as&lt;br /&gt;&lt;code&gt;       &amp;lt;xmlpoke file="${wix.file}" xpath="/Wix/Product/@Version"                value="${build.new.version}"/&amp;gt;&lt;/code&gt;&lt;br /&gt;does not work.&lt;br /&gt;&lt;br /&gt;What it does work is the following use of the task:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;      &amp;lt;xmlpoke file="${wix.file}" xpath="/wx:Wix/wx:Product/@Version" value="${build.version}"&amp;gt;&lt;br /&gt;               &amp;lt;namespaces&amp;gt;&lt;br /&gt;       &amp;lt;namespace prefix="wx" uri="http://schemas.microsoft.com/wix/2003/01/wi" /&amp;gt;&lt;br /&gt;    &amp;lt;/namespaces&amp;gt;&lt;br /&gt;      &amp;lt;/xmlpoke&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-116292503813978641?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/116292503813978641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=116292503813978641&amp;isPopup=true' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116292503813978641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116292503813978641'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/11/problem-with-nants-xmlpoke-task.html' title='Problem with NAnt&apos;s xmlpoke task'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-116292391105459005</id><published>2006-11-07T15:24:00.000-03:00</published><updated>2006-11-07T15:25:12.226-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nant'/><title type='text'>NAnt.Contrib</title><content type='html'>&lt;a href="http://nantcontrib.sourceforge.net/"&gt;NAnt Contrib&lt;/a&gt; is a project that &lt;span style="font-style: italic;"&gt;contributes&lt;/span&gt; with a lot of additional tasks to NAnt. For example, two of the most useful tasks for me are the &lt;span style="font-weight: bold;"&gt;trycatch &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;choose &lt;/span&gt;tasks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-116292391105459005?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/116292391105459005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=116292391105459005&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116292391105459005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/116292391105459005'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/11/nantcontrib.html' title='NAnt.Contrib'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-115672148257205368</id><published>2006-08-27T20:25:00.000-03:00</published><updated>2006-08-27T20:35:05.993-03:00</updated><title type='text'>MSDN Conference's Material</title><content type='html'>The presentation of &lt;a href="http://solepano.blogspot.com/2006/08/msdn-conference.html"&gt;the conference&lt;/a&gt; about "Testing and guarantee of quality with Visual Studio Team System" that we gave at Microsoft last Thursday can be downloaded from &lt;a href="http://weblogs.shockbyte.com.ar/rodolfof/archive/2006/08/25/8848.aspx"&gt;Rodolfo's blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-115672148257205368?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/115672148257205368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=115672148257205368&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115672148257205368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115672148257205368'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/08/msdn-conferences-material.html' title='MSDN Conference&apos;s Material'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-115609816337780858</id><published>2006-08-20T15:20:00.000-03:00</published><updated>2006-08-20T23:32:41.976-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code analysis'/><title type='text'>How to add a custom rule to VSTS Code Analysis</title><content type='html'>The code analysis feature that ships with Visual Studio Team System (VSTS), FxCop, comes with a rich API to write custom rules. Since the API almost lacks of documentation, I've been struggling for a while before I got my custom rules to work. That's why I've decided to write this short guide on how to make your own rules: (It is required that you have the VSTS version of Visual Studio 2005 intalled)&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a new class library project.&lt;/li&gt;&lt;li&gt;   Add references to the &lt;span style="font-style: italic;"&gt;Microsoft.cci.dll&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;FxCopSdk.dll&lt;/span&gt; assemblies (typically installed in C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop).&lt;/li&gt;&lt;li&gt;Create your custom rule class and make it derive from &lt;span style="font-style: italic;"&gt;BaseIntrospectionRule.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Make the constructor of your class call its base constructor, which has three parameters: the rule's name, the name of the rule descriptor file (see step 4), and the assembly that contains the rule. Note that, if your project will consist on more than a single rule, it is convenient to write your own base class for all the rules not to repeat code.&lt;/li&gt;&lt;li&gt;I took as example the base class of the FxCop design rules:&lt;br /&gt;&lt;pre class="code"&gt;using System;&lt;br /&gt;using Microsoft.Cci;&lt;br /&gt;using Microsoft.FxCop.Sdk;&lt;br /&gt;using Microsoft.FxCop.Sdk.Introspection;&lt;br /&gt;&lt;br /&gt;namespace Microsoft.FxCop.Rules.Design{&lt;br /&gt;&lt;br /&gt;  internal abstract class DesignIntrospectionRule &lt;br /&gt;           &lt;b&gt;: BaseIntrospectionRule&lt;/b&gt; {&lt;br /&gt;&lt;br /&gt;    protected DesignIntrospectionRule(string name)&lt;br /&gt;      &lt;b&gt;: base(name, &lt;br /&gt;            "Microsoft.FxCop.Rules.Design.DesignRules",&lt;br /&gt;            typeof(DesignIntrospectionRule).Assembly)&lt;/b&gt; {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override void AfterAnalysis(){&lt;br /&gt;       DesignRuleUtilities.Clear();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Override one of the Check methods to implement your custom rule's logic. Here's a snippet of one of the design rules that overrides the Check(TypeNode) method. Other Check overloads are available, for checking members, types, modules, etc. If it happends that the target being analyzed does not match the rule's condition, a new Problem is added to the Problems collection, and this collection is returned by the check method. The GetResolution method allows you to fetch a resolution from the rules xml file. &lt;br&gt;&lt;br /&gt;&lt;pre class="code"&gt;internal sealed class AbstractTypesShouldNotHaveConstructors &lt;br /&gt;   : DesignIntrospectionRule {&lt;br /&gt;&lt;br /&gt;public AbstractTypesShouldNotHaveConstructors()&lt;br /&gt;   : base("AbstractTypesShouldNotHaveConstructors") {&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public override ProblemCollection Check(TypeNode type) {&lt;br /&gt;   if (!type.IsAbstract) {&lt;br /&gt;       return null;&lt;br /&gt;   }&lt;br /&gt;   for (int num1 = 0; num1 &amp;lt; type.Members.Length; num1++) {&lt;br /&gt;        InstanceInitializer initializer1 = type.Members[num1] &lt;br /&gt;                    as InstanceInitializer;&lt;br /&gt;        if ((initializer1 != null) &amp;&amp;amp; initializer1.IsPublic) {&lt;br /&gt;           Resolution resolution1 = base.GetResolution(new string[]&lt;br /&gt;                                        { type.Name.Name });&lt;br /&gt;           Problem problem1 = new Problem(resolution1);&lt;br /&gt;           base.Problems.Add(problem1);&lt;br /&gt;           break;&lt;br /&gt;        }&lt;br /&gt;   }&lt;br /&gt;   return base.Problems;&lt;br /&gt; }&lt;br /&gt; ...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Eventually override the BeforeAnalysis or AfterAnalysis methods if you need to execute something before or after the analysis process takes place respectivelly.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Add the rules .xml descriptor file to the project as an embedded resource, with the not copy to the target directory option set. The file's name (including it's namespace, and without the extension) must match the second parameter of the BaseIntrospectionRule constructor. It seems that there's no schema available for the xml, but here's a portion of the DesignRules descriptor:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&amp;lt;Rules FriendlyName="Design Rules"&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;Rule TypeName="AbstractTypesShouldNotHaveConstructors" &lt;br /&gt;         Category="Microsoft.Design" &lt;br /&gt;         CheckId="CA1012"&amp;gt;&lt;br /&gt;&amp;lt;Name&amp;gt;Abstract types should not have constructors&amp;lt;/Name&amp;gt;&lt;br /&gt;&amp;lt;Description&amp;gt;Public constructors for abstract types do &lt;br /&gt;   not make sense because you cannot create instances of &lt;br /&gt;   abstract types.&amp;lt;/Description&amp;gt;&lt;br /&gt;&amp;lt;Url&amp;gt;/Design/AbstractTypesShouldNotHaveConstructors.html&amp;lt;/Url&amp;gt;&lt;br /&gt;&amp;lt;Resolution&amp;gt;Change the accessibility of all public constructors &lt;br /&gt;     in '{0}' to protected.&amp;lt;/Resolution&amp;gt;&lt;br /&gt;&amp;lt;Email&amp;gt;&lt;br /&gt;&amp;lt;/Email&amp;gt;&lt;br /&gt;&amp;lt;MessageLevel Certainty="95"&amp;gt;CriticalWarning&amp;lt;/MessageLevel&amp;gt;&lt;br /&gt;&amp;lt;FixCategories&amp;gt;NonBreaking&amp;lt;/FixCategories&amp;gt;&lt;br /&gt;&amp;lt;Owner /&amp;gt;&lt;br /&gt;&amp;lt;/Rule&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Rules&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Integrate the custom rules with visual studio's code analysis&lt;br /&gt;&lt;ul&gt;&lt;li&gt;In order to register your rules with VS, you just need to copy the assembly containing your rules to the rules directory (c:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\Rules).&lt;/li&gt;&lt;li&gt;All the rules contained in the assembly will be enabled by default.&lt;/li&gt;&lt;li&gt;You can now simply run the code analysis over a project to evaluate it with your own rules.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-115609816337780858?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115609816337780858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115609816337780858'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/08/how-to-add-custom-rule-to-vsts-code.html' title='How to add a custom rule to VSTS Code Analysis'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-115447920155183830</id><published>2006-08-01T21:08:00.000-03:00</published><updated>2006-08-03T21:24:49.983-03:00</updated><title type='text'>MSDN Conference</title><content type='html'>This month I will take a little part in an MSDN conference at Microsoft Argentina. Along with &lt;a href="http://weblogs.asp.net/dgonzalez/"&gt;Diego Gonzalez&lt;/a&gt; and &lt;a href="http://weblogs.shockbyte.com.ar/rodolfof/"&gt;Rodolfo Finochietti&lt;/a&gt; we will speak about &lt;span style="font-weight: bold;"&gt;Testing and quality assurance with Visual Studio Team System (VSTS)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;It is the first time I am backwards the blackboard at a Microsoft's conference, so I am very enthusiastic about that. I hope to see everyone there. It is on August 24th and &lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032304757&amp;amp;Culture=es-AR"&gt;here&lt;/a&gt;'s the link to register.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-115447920155183830?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115447920155183830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115447920155183830'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/08/msdn-conference.html' title='MSDN Conference'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-115203426152882939</id><published>2006-07-04T14:29:00.000-03:00</published><updated>2006-11-08T10:29:03.373-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net 3.0'/><title type='text'>Starting developing  in .Net Framework 3.0</title><content type='html'>Here's a&lt;span style="font-style: italic;"&gt; how to &lt;/span&gt;start developing .Net Framework 3.0 applications.&lt;br /&gt;&lt;br /&gt;For any doubts on OS and framework's compatibility, read the article &lt;a href="http://msdn.microsoft.com/winfx/default.aspx?pull=/library/en-us/dnlong/html/netfx30.asp"&gt;Deploying .Net Framework 3.0&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's nedded for developing .Net3 applications &lt;/span&gt;&lt;span style="font-size:85%;"&gt;(taken from &lt;a href="http://msdn.microsoft.com/windowsvista/downloads/products/getthebeta/#developWinFXApps"&gt;here&lt;/a&gt;)&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&amp;displaylang=en"&gt;.Net Framework 3 Runtime Components&lt;/a&gt; (already ships with WindowsVista and Longhorn)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;amp;displaylang=en"&gt;Windows SDK&lt;/a&gt;: includes the documentation, samples, tools and build environments to develop Windows applications - either native or .NET Framework 3.0.&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;[Optional] &lt;span style="font-weight: bold;"&gt;Visual Studio 2005&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;[Optional] &lt;b&gt;&lt;span style="font-weight: bold;"&gt;"Orcas" .NET Framework 3.0 Development Tools&lt;/span&gt;: &lt;/b&gt; development tools that work with Visual Studio 2005 and provide functionality such as XAML Intellisense support through schema extensions for the editor, project templates for the Windows Presentation Foundation and Windows Communication Foundation namespaces and .NET Framework 3.0 SDK documentation integration. &lt;/li&gt;&lt;li&gt;[Optional] &lt;b&gt;Visual Studio 2005 Extensions for Windows Workflow Foundation:&lt;/b&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=63A80A4B-BD27-4124-A2A5-61786ADB626E&amp;amp;displaylang=en" target="_blank"&gt;extensions to Visual Studio 2005&lt;/a&gt; include project templates, intellisense support for the Workflow namespace (System.Workflow) and integrated documentation.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-115203426152882939?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115203426152882939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115203426152882939'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/07/starting-developing-in-net-framework.html' title='Starting developing  in .Net Framework 3.0'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-115203209654809570</id><published>2006-07-04T13:54:00.000-03:00</published><updated>2006-07-05T12:01:08.500-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net 3.0'/><title type='text'>.Net Glossary 3.0</title><content type='html'>This is just a summary of the new terms incorporated by the third generation of the .Net Framework.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://msdn.microsoft.com/winfx/default.aspx"&gt;.Net Framework 3.0&lt;/a&gt; (&lt;a href="http://en.wikipedia.org/wiki/Project_code_name"&gt;codename&lt;/a&gt; WinFX)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;        The new managed-code programming model for Windows.&lt;br /&gt;      It's basically the sum of the .NET Framework 2.0 plus some new technologies.&lt;br /&gt;      It will ship with Windows Vista.&lt;br /&gt;      It is available for Windows XP and 2000 with SP2 and for Windows Server 2003.&lt;br /&gt;      Here's the .Net Framework  3.0's diagram (stolen from MSDN):&lt;br /&gt;      &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/444/2419/1600/dotnetFx3.0.gif"&gt;&lt;img style="margin: 0pt 0pt 0px 0px; cursor: pointer;" src="http://photos1.blogger.com/blogger/444/2419/320/dotnetFx3.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Authentic Energic Reflexive Open (AERO)&lt;/span&gt;: Windows Vista's Look &amp; Feel. Refers back to the UX Guidelines.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://msdn.microsoft.com/winfx/reference/infocard/default.aspx"&gt;Card Space&lt;/a&gt; (ex InfoCard): &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Unified Digital Identity.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;eXtensible Application Markup Language (XAML)&lt;/span&gt;: XML based languaged used to  code the WPF's object model.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Microsoft Expression&lt;/span&gt;&lt;span class="content"&gt;: multimedia software package for graphic designers. It ships with 3 applications:&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="content"&gt;&lt;span style=";font-family:Arial,Helvetica,sans-serif;font-size:85%;"  &gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;span style="font-weight: bold;"&gt;Acrilyc Graphic  Designer&lt;/span&gt;: Design tool compatible with bitmaps and vectorial graphics.   &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="content"&gt;&lt;span style=";font-family:Arial,Helvetica,sans-serif;font-size:85%;"  &gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;span style="font-weight: bold;"&gt;Sparkle Interactive Designer&lt;/span&gt;: XAML, MS alternative to Macromedia Flash.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="content"&gt;&lt;span style=";font-family:Arial,Helvetica,sans-serif;font-size:85%;"  &gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;span style="font-weight: bold;"&gt;Quartz Web Designer&lt;/span&gt;: MS Frontpage's replacement.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;ORCAS&lt;/span&gt;: codename for the next version of Visual Studio.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://msdn.microsoft.com/vstudio/teamsystem/team/default.aspx"&gt;Team Foundation Server&lt;/a&gt; (TFS)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-weight: bold;"&gt;:&lt;/span&gt; workflow collaboration engine that enables the use of a team's customized process, as well as a centralized data warehouse that collects real-time intelligence on project history.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://msdn.microsoft.com/data/ref/linq/"&gt;The LINQ Proyect&lt;/a&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/data/ref/linq/"&gt;:&lt;/a&gt; codename&lt;span style="color: rgb(0, 0, 0);"&gt; for a set of extensions to the .NET Framework that encompass Language-INtegrated Query, set, and transform operations. It extends C# and Visual Basic with native language syntax for queries and provides class libraries to take advantage of these capabilities.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a style="font-weight: bold;" href="http://msdn.microsoft.com/windowsvista/reference/presentation/default.aspx?pull=/library/en-us/uxguide/uxguide/home.asp"&gt;User Experience (UX) Guidelines&lt;/a&gt; &lt;span style="font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-weight: bold;"&gt;UX Guide)&lt;/span&gt;: &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Contain information on what’s new in Windows Vista, design principles, guidelines for controls, text, windows, and aesthetics. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://msdn.microsoft.com/winfx/technologies/communication/"&gt;Windows Comunication Foundation&lt;/a&gt; (WCF) (codename Indigo)&lt;/span&gt;: Unified set of technologies to build Service Oriented Applications.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://msdn.microsoft.com/winfx/reference/presentation/default.aspx"&gt;Windows Presentation Foundation&lt;/a&gt; (WPF) (codename Avalon)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/windowsvista/"&gt;&lt;span style="font-weight: bold;"&gt;WindowsVista&lt;/span&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt; (codename Longhorn)&lt;/span&gt;: Major Windows Operating System&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://msdn.microsoft.com/winfx/reference/workflow/default.aspx"&gt;Windows Workflow Foundation&lt;/a&gt; (WF): &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;programming model, engine and tools for quickly building workflow enabled applications.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-115203209654809570?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115203209654809570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115203209654809570'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/07/net-glossary-30.html' title='.Net Glossary 3.0'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-115202171215406445</id><published>2006-07-04T09:44:00.000-03:00</published><updated>2006-07-13T12:38:23.016-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code analysis'/><title type='text'>Dependencies Metrics</title><content type='html'>In his paper about &lt;a href="http://www.objectmentor.com/resources/articles/stability.pdf"&gt;Stability (1997)&lt;/a&gt;, &lt;span style="font-weight: bold;"&gt;Robert C. Martin&lt;/span&gt; describes a set of principles and metrics that can be used to measure the quality of a large object oriented designed proyect in terms of the interdependence between its packages.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The metrics&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Abstract types&lt;/span&gt;: The number of abstract types contained in the assembly.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Total types:&lt;/span&gt; The number of total types contained in the assembly.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Abstractness (A):&lt;/span&gt; The ratio of abstract types in the assembly to the total number            of types. A = abstract types / total types.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Efferent Couplings (Ce): &lt;/span&gt;The number of types inside the assembly that depend upon types outside the assembly.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Afferent Couplings (Ca):&lt;/span&gt; The number of types outside the assembly that depend upon types within the assembly.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Instability (I):&lt;/span&gt; I = Ce / (Ce+Ca). Measure of the facility in changing the assembly.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Distance from the Main Sequence (D):&lt;/span&gt; In an Abstraction vs Instability space, the distance from the assembly (I,A) possition to the &lt;span style="font-weight: bold;"&gt;Main Sequence&lt;/span&gt; (the line of maximum balance between abstractness and instability). D = |A+I-1|/sqrt(2)&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Normalized Distance (D'):&lt;/span&gt; The above distance ranged between [0,1]. D’ = |A+I-1|&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The Principles&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Stable Abstraction Principle (SAP): &lt;/span&gt;Reference's direction must be from a less abstract to a more abstract assembly.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Stable Dependency Principle (SDP): &lt;/span&gt;Reference's directon must be from a more instable assembly to a more stable assembly.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Examples&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:Arial;font-size:85%;"  &gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/444/2419/1600/badReference.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/444/2419/320/badReference.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;- The figure on the left shows a &lt;span style="font-weight: bold;"&gt;bad dependency &lt;/span&gt;(the red arrow) because As1 depends on As2, but As2 in less abstract than As1 and more instable too.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/444/2419/1600/goodDependency.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/444/2419/320/goodDependency.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;-&gt; The figure on the right shows a &lt;span style="font-weight: bold;"&gt;good dependency  &lt;/span&gt;because it goes in the abstraction's direction (As1 is more abstract thanAs2) and also in the stability's direction (As1 is more stable -less instable- than As2).&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Why to use them&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;They are easy to calculate (already exists tools to do the job -at least for java-)&lt;/li&gt;&lt;li&gt;They are widely used and approved.&lt;/li&gt;&lt;li&gt;They will help a lot in determining the proyect's health in terms of its dependencies, although it is possible that not ALL references seen as bad references below the eye of this principles are REALLY bad references.&lt;/li&gt;&lt;li&gt;They allow to continuously monitor the quality aspects of code that can affect the long-term viability of your software architecture.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Tools for calculating them&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For Java:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://refactorit.com/?id=29678"&gt;RefactorIT&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://clarkware.com/software/JDepend.html"&gt;JDepend&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www-128.ibm.com/developerworks/java/library/j-cq04256/index.html"&gt;IBM&lt;/a&gt; - &lt;a href="http://sourceforge.net/projects/metrics"&gt;Eclipse Metrics plugin&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://aopmetrics.tigris.org/"&gt;Tigris' AopMetrics&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;etc...&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;For .Net:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-115202171215406445?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115202171215406445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115202171215406445'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/07/dependencies-metrics.html' title='Dependencies Metrics'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-115077545768451545</id><published>2006-06-20T00:50:00.000-03:00</published><updated>2006-06-22T15:33:49.486-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>Testing Data Access Layers (DALs)</title><content type='html'>It seems that testing DALs is harder than I thought. One of the problems I have run into is how to preserve DB integrity. Some of the alternatives are:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Create mock objects that replace the database.&lt;/li&gt;   &lt;li&gt;Have a separate DB for testing.&lt;/li&gt;   &lt;li&gt;Restore the DB on every test run.&lt;/li&gt;   &lt;li&gt;Run the test inside transactions and then rollback.&lt;/li&gt; &lt;/ol&gt; Another concern is: How the tests must be designed in order for their success or failure to depend only on the coding and not on the data state?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Related Links&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Testing Frameworks:&lt;br /&gt;&lt;a href="http://www.ondotnet.com/pub/a/dotnet/2005/07/18/unittesting_2005.html"&gt;&lt;br /&gt;Unit Testing in .Net Proyects&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:85%;"&gt; by Jay Flowers&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Transaction approach:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/06/UnitTesting/default.aspx"&gt;Simplify Data Layer Unit Testing using Enterprise Services&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/06/UnitTesting/default.aspx?side=true#a"&gt;Alternative Testing Frameworks&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Mock Objects:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/04/10/NMock/"&gt;Mock Objects to the Rescue! Test your .NET code with NMock&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.martinfowler.com/articles/mocksArentStubs.html"&gt;Mocks Aren't Stubs&lt;/a&gt; by Martin Fowler&lt;br /&gt;&lt;br /&gt;Testing sequences (useful for CRUD operations):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/csharp/autp3.asp"&gt;Advanced Unit Testing, Part III - Testing Processes&lt;/a&gt; by Marc Clifton&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-115077545768451545?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115077545768451545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/115077545768451545'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/06/testing-data-access-layers-dals.html' title='Testing Data Access Layers (DALs)'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-114865607896660990</id><published>2006-05-26T12:01:00.000-03:00</published><updated>2006-06-07T14:42:10.303-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><title type='text'>DSL Tools for VS2005</title><content type='html'>This is a guide for &lt;span style="font-weight: bold;"&gt;Building a DSL Designer using the DSL Tools for VS2005&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Pre-requisites:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;These components must be intalled:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Visual Studio 2005&lt;/li&gt;&lt;li&gt;Visual Studio 2005 SDK&lt;/li&gt;&lt;li&gt;DSL Tools for Visual Studio 2005&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. Create a new project in VS2005&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The project template must be: Other Project Types -&gt; Extensibility -&gt; Domain Specific Language Designer.&lt;br /&gt;&lt;br /&gt;Choose a template for the designer.&lt;br /&gt;&lt;br /&gt;Note that VS has created a solution with 2 projects: Designer and DomainModel.&lt;br /&gt;&lt;br /&gt;A DSL Designer consists of 3 components:&lt;br /&gt;&lt;br /&gt; 1. Domain elements (Domain Model)&lt;br /&gt; 2. Notational elements&lt;br /&gt; 3. Mapping between Domain and Notational elements&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. The Domain Model&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Domain Model is in the DomainModel.dsldm in the DomainModel Project. You can edit it by gragging and dropping the Domain Model Designer Tools of the Toolbox.&lt;br /&gt;&lt;br /&gt;The Model contains classes and relationships. Classes may contain value properties.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3. The Notation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Notation is represented in an xml file. The default description is in the file Designer.dsldd in the Designer Project.&lt;br /&gt;&lt;br /&gt;The notation can include shapes which appear in the toolbox and can be dragged onto the design surface, connector for the shapes, etc.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4. Domain-Notation Mapping&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is also defined in the dsldd file. In general the mapping is between shapes and connector lines to classes and relationships respectively. So when a user creates shapes and connectors in the designer he also creates the classes and relationships in the domain.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5. Generate code and build&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Click on the "Transform All Templates" button in the Solution Explorer Toolbar.&lt;br /&gt;Build the solution.&lt;br /&gt;Press Ctrl+F5 to run the designer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;6. Consuming the DSL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Templates consist of some directives followed by a mixture of literal blocks and control blocks. Literal blocks are just plain text in the template that you want to pass straight through to the output. Control blocks are things with some kind of &lt;# #&gt; marker around them.&lt;br /&gt;&lt;br /&gt;The content of these blocks in your template contributes to a class which the templating system generates. This class derives from the abstract class Microsoft.VisualStudio.TextTemplating.TextTransformation and overrides the abstract method TransformText which, when executed, writes out the desired output of the transformation of the template. If you do nothing else in your template, this method will write out all of the text in literal blocks by simply writing out the raw text using a simple WriteLine()-style statement. The base class provides this WriteLine method (in various flavors) as well as Error and Warning methods that you can use in your custom template code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;7. Deployment&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Add a Setup package to build a deployable designer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-114865607896660990?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/114865607896660990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=114865607896660990&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114865607896660990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114865607896660990'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/05/dsl-tools-for-vs2005.html' title='DSL Tools for VS2005'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-114865564702253076</id><published>2006-05-26T11:37:00.000-03:00</published><updated>2006-06-13T12:33:19.216-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><title type='text'>DSL - A first approach to.</title><content type='html'>This is a summary of the Martin Fowler's article on &lt;a href="http://www.martinfowler.com/articles/languageWorkbench.html"&gt;Language Workbenches: The Killer-App for Domain Specific Languages?&lt;/a&gt; which I have recently read and found very interesting.&lt;br /&gt;&lt;h2&gt;&lt;a name="_Toc127640637"&gt;&lt;span style=""&gt;Terminology&lt;/span&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;    &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style=""&gt;Language Workbench&lt;/span&gt;&lt;/b&gt;&lt;span style=""&gt;: IDE tools to help &lt;b style=""&gt;Language Oriented Programming&lt;/b&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style=""&gt;Language Oriented Programming&lt;/span&gt;&lt;/b&gt;&lt;span style=""&gt;: a style of development which operates about the idea  of building software around a set of &lt;b style=""&gt;Domain Specific Languages&lt;/b&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style=""&gt;Domain Specific Language (DSL)&lt;/span&gt;&lt;/b&gt;&lt;span style=""&gt;: Limited form of computer language designed for a specific class of problems.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;&lt;a name="_Toc127640638"&gt;&lt;span style=""&gt;DSL&lt;/span&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Imagine you build a class library to solve some particular problem and that the objects involved are parameterizable. So, you need a first step to set up configuration and wire up composite objects before putting them to do the work.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;When building this kind of class library, there is a marked distinction between the abstraction itself and the configuration. The abstraction may be reusable and less often to change, while the configuration tends to be specific, more simple, and likely to change more often.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;This leads to the idea of putting the configuration out of the code, for example, in xml files or in some custom syntax file (what may be more readily). The structure of this configuration, the mapping with the objects in the abstraction, the parameters, etc, are nothing but a kind of Domain Specific Language, a very small programming language, suitable for the only purpose of solving some specific problem.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;If we leave the configuration in the code, instead of moving it to a configuration file, we still have a case of DSL, a DSL embedded in the host language. So here comes the distinction between &lt;b style=""&gt;internal and external DSL&lt;/b&gt;. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;External DSL: DSL written in a different language than the main language of an application.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Internal DSL: DSL written in the same language of the main language of an application.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc127640639"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;h2&gt;&lt;span style=""&gt;&lt;span style=""&gt;Language Oriented Programming&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Language oriented programming is about describing a system through multiple DSLs. It does not have to be a black or white thing; you can represent little or a lot of functionality of your system in DSLs.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;  &lt;/p&gt;&lt;h2&gt;&lt;a name="_Toc127640640"&gt;&lt;span style=""&gt;Pros and Cons of Language Oriented Programming&lt;/span&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;table class="MsoTableGrid" style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0"&gt;  &lt;tbody&gt;&lt;tr style=""&gt;   &lt;td colspan="2" style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 432.2pt;" valign="top" width="576"&gt;   &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;External DSL&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; padding: 0in 5.4pt; width: 216.1pt;" valign="top" width="288"&gt;   &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Pros&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; padding: 0in 5.4pt; width: 216.1pt;" valign="top" width="288"&gt;   &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Cons&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; padding: 0in 5.4pt; width: 216.1pt;" valign="top" width="288"&gt;   &lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Parameters        can be changed without recompiling. Evaluated at runtime. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Format /        grammar free.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; padding: 0in 5.4pt; width: 216.1pt;" valign="top" width="288"&gt;   &lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;A translator        needs to be built.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Lack of        symbolic integration.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Refactoring will        not propagate to the DSL.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Lack of        sophisticated editor.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Language        cacophony: a new language must be learned. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Difficulty of        designing DSLs.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;table class="MsoTableGrid" style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0"&gt;  &lt;tbody&gt;&lt;tr style=""&gt;   &lt;td colspan="2" style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 432.2pt;" valign="top" width="576"&gt;   &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Internal DSL&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; padding: 0in 5.4pt; width: 216.1pt;" valign="top" width="288"&gt;   &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Pros&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; padding: 0in 5.4pt; width: 216.1pt;" valign="top" width="288"&gt;   &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Cons&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; padding: 0in 5.4pt; width: 216.1pt;" valign="top" width="288"&gt;   &lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Symbolic        Integration.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Host language        IDE can be used.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Easy        refactoring.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Sophisticated        editors.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; padding: 0in 5.4pt; width: 216.1pt;" valign="top" width="288"&gt;   &lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Recompilation        required when making changes (in most languages).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Format /        grammar free.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: justify;"&gt;  &lt;/p&gt;&lt;h2&gt;&lt;a name="_Toc127640641"&gt;&lt;span style=""&gt;Language Workbenches&lt;/span&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;Language Workbenches are complex tools that help implementing DSLs. They are based on the same model as post-IntelliJ IDEs, which consists of having four different representations of the code:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style=""&gt;Abstract representation&lt;/span&gt;&lt;/b&gt;&lt;span style=""&gt;: In-memory representation. Helps with things like name completion and refactoring. It is the key persistent source that you manipulate (through the editable representation). It can persist incomplete or contradictory information.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style=""&gt;Editable representation&lt;/span&gt;&lt;/b&gt;&lt;span style=""&gt;: Projection of the abstract representation in order to edit it. It does not have to be complete. There can be multiple projections, one for each aspect.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style=""&gt;Storage&lt;/span&gt;&lt;/b&gt;&lt;span style=""&gt; &lt;b style=""&gt;representation&lt;/b&gt;: Serialization of the abstract representation, often as XML.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style=""&gt;Executable&lt;/span&gt;&lt;/b&gt;&lt;span style=""&gt; &lt;b style=""&gt;representation&lt;/b&gt;: The CLR byte code. A code generator turns the abstract representation into the executable representation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;So, when defining a new DSL you need to:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;ul type="disc"&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=""&gt;Define the abstract syntax, the &lt;b&gt;schema&lt;/b&gt; of the abstract      representation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=""&gt;Define an &lt;b&gt;editor&lt;/b&gt; to let people manipulate the abstract      representation through a projection. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=""&gt;Define a &lt;b&gt;generator &lt;/b&gt;to translate the abstract representation into an executable representation. In practice the generator defines the semantics of the DSL.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;p class="MsoNormal" style="text-align: justify;"&gt;&lt;span style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;    &lt;a name="_Toc127640640"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-114865564702253076?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/114865564702253076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=114865564702253076&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114865564702253076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114865564702253076'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/05/dsl-first-approach-to.html' title='DSL - A first approach to.'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-114674862383421025</id><published>2006-05-04T10:12:00.000-03:00</published><updated>2006-05-04T10:17:03.843-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>Configuration Files &amp; NUnit</title><content type='html'>When using an application configuration file (App.config) in a nunit library application project, the following post build event is needed to copy the config file to the target directory:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;copy "$(ProjectDir)App.config" "$(TargetPath).config"&lt;br /&gt;&lt;/span&gt;Once this is done, we can access any configuration item through:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;System.Configuration.ConfigurationSettings.AppSettings["myConfigItem"]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-114674862383421025?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/114674862383421025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=114674862383421025&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114674862383421025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114674862383421025'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/05/configuration-files-nunit.html' title='Configuration Files &amp; NUnit'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-114182890856407420</id><published>2006-03-08T11:38:00.000-03:00</published><updated>2006-06-20T10:13:36.080-03:00</updated><title type='text'>Generating Documentation for .NET Project</title><content type='html'>&lt;p class="MsoNormal"&gt;Suppose we need to generate documentation for a .net project in the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/hworiHTMLHelpStartPage.asp"&gt;Microsoft HTML Help&lt;/a&gt; style, more known as .chm files. Different tools can be used depending on what it is being documenting.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt; Documenting code&lt;/b&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;We can use &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcoriXMLDocumentation.asp"&gt;xml documentation&lt;/a&gt; by placing comments inside xml tags (like &amp;lt;summary&amp;gt; or &amp;lt;remarks&amp;gt;) within any line beginning with three space bars&lt;summary&gt; &lt;remarks&gt;. For a complete tag reference see &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrfTagsForDocumentationComments.asp"&gt;TagsForDocumentationComments&lt;/a&gt; .  &lt;/remarks&gt;&lt;/summary&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;The C# compiler processes documentation comments within the code to an XML file. This is done in the build process if the &lt;span style="font-style: italic;"&gt;documentation xml file&lt;/span&gt; was specified in the project's build properties. (Notice that a lot of warnings about documentation will prompt if warning level is set to 4 in the project properties.)&lt;br /&gt;&lt;br /&gt;Now, once we have the xml file, we want to parse it in order to generate easy reading documentation. Luckily, there is a free tool that does that: &lt;a href="http://ndoc.sourceforge.net/"&gt;NDoc&lt;/a&gt;. Ndoc provides several output formats, including the MSDN one.&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;b style=""&gt;Including custom content in the chm file&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;         &lt;p class="MsoNormal"&gt;If we need to include custom content in the chm file, other than the code documentation generated by NDoc, we have to write it in HTML format and then compile it into the chm file. The &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/vsconhh1start.asp"&gt;HTML Help SDK&lt;/a&gt; can be used for the last purpose. The SDK shipps with a tool, the HTML Help Workshop (&lt;installdir&gt;\hhw.exe), that is used to create HTML Help Projects.&lt;br /&gt;&lt;/installdir&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;An HTML Help project consists of three parts:&lt;br /&gt;&lt;/p&gt;    &lt;ul type="disc"&gt; &lt;li class="MsoNormal" style=""&gt;The Project itself (.hhp file)&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;The Table of Contents (.hhc file)&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;The Index (.hhk file)&lt;/li&gt; &lt;/ul&gt; &lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style=""&gt;Documenting XML schemas&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;It seems that the documentation of xml schemas is a little more complicated task. First we need to place comments inside the schema and then we need to generate the HTML help from them.&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;In order to place documentation inside an xml schema, the &lt;a href="http://www.w3.org/TR/xmlschema11-1/#cAnnotations"&gt;annotation&lt;/a&gt; component can be used..&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;      &lt;p class="MsoNormal"&gt;But again, a way for generating the HTML Help from the documented schema is needed. This time I have found no free tool to do that. I have found a nice tool,&lt;a href="http://www.innovasys.com/products/dx5/overview.asp"&gt; Document!X&lt;/a&gt;, neither free nor open source. So, I decided to generate the MSDN documentation myself by transforming the xsd file into an HTML help file through a style sheet. The generated HTML file is later included in the chm file as any else custom content.&lt;b style=""&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;Links:&lt;br /&gt;&lt;p class="MsoNormal"&gt;http://www.mshelpwiki.com/index.php?&lt;br /&gt;http://www.microsoft.com/downloads/details.aspx?familyid=ce1b26dc-d6af-42a1-a9a4-88c4eb456d87&amp;amp;displaylang=en&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-114182890856407420?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/114182890856407420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=114182890856407420&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114182890856407420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114182890856407420'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/03/generating-documentation-for-net.html' title='Generating Documentation for .NET Project'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23538096.post-114168172526133510</id><published>2006-03-06T18:34:00.000-03:00</published><updated>2006-03-06T23:44:43.033-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogs'/><title type='text'>Blog's Birth</title><content type='html'>&lt;span style="font-weight: bold;"&gt;My blog has born at last!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What is this blog about? This is a developer's blog, so just technical issues will be posted. The idea is to use this blog as a sort of knowlage base, just to write the daily little research and findings, for others to read and for me to remember. I was definitely needing a place to store all my writings and links and stuff, so I am very happy for this beginning and hope to keep it updated.&lt;br /&gt;&lt;br /&gt;Of course averyone is welcome to contribute by posting comments or contact me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23538096-114168172526133510?l=solepano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://solepano.blogspot.com/feeds/114168172526133510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23538096&amp;postID=114168172526133510&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114168172526133510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23538096/posts/default/114168172526133510'/><link rel='alternate' type='text/html' href='http://solepano.blogspot.com/2006/03/blogs-birth.html' title='Blog&apos;s Birth'/><author><name>Sole</name><uri>http://www.blogger.com/profile/11860446136334866875</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://photos1.blogger.com/blogger/444/2419/1600/fotoMsn2.jpg'/></author><thr:total>1</thr:total></entry></feed>
