<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Fluent</title>
        <link>http://geekswithblogs.net/EltonStoneman/category/10643.aspx</link>
        <description>Fluent</description>
        <language>en-GB</language>
        <copyright>Elton Stoneman</copyright>
        <managingEditor>comments@sixeyed.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Mapping and Auto-Mapping Objects</title>
            <link>http://geekswithblogs.net/EltonStoneman/archive/2012/01/03/mapping-and-auto-mapping-objects.aspx</link>
            <description>&lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal" align="center"&gt;&lt;span&gt;&lt;font style="font-size: 10pt"&gt;[Source: &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 10pt"&gt;&lt;a href="http://geekswithblogs.net/EltonStoneman"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;http://geekswithblogs.net/EltonStoneman&lt;/font&gt;&lt;/span&gt;&lt;/a&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 10pt"&gt;]&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;This is the first of a series of posts covering my generic &lt;span style="mso-spacerun: yes"&gt; &lt;/span&gt;anything-to-object mapping library on github: &lt;a href="https://github.com/sixeyed/projects/tree/master/Sixeyed.Mapping"&gt;&lt;font color="#800080"&gt;Sixeyed.Mapping&lt;/font&gt;&lt;/a&gt;.&lt;/p&gt;  &lt;p style="text-indent: -18pt; margin: 0cm 0cm 0pt 36pt; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpFirst"&gt;&lt;span style="mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;span style="mso-list: ignore"&gt;1.&lt;span style="line-height: normal; font-family: "&gt;&lt;font face="Times New Roman"&gt;&lt;font style="font-size: 7pt"&gt;       &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Mapping and Auto-Mapping Objects&lt;/p&gt;  &lt;p style="text-indent: -18pt; margin: 0cm 0cm 0pt 36pt; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpMiddle"&gt;&lt;a href="http://geekswithblogs.net/EltonStoneman/archive/2012/01/04/mapping-and-auto-mapping-objects-from-idatareader.aspx"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin; mso-themecolor: background1; mso-themeshade: 166"&gt;&lt;span style="mso-list: ignore"&gt;2.&lt;span style="line-height: normal; font-family: "&gt;&lt;font face="Times New Roman"&gt;&lt;font style="font-size: 7pt"&gt;       &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-themecolor: background1; mso-themeshade: 166"&gt;Mapping and Auto-Mapping Objects from IDataReader&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p style="text-indent: -18pt; margin: 0cm 0cm 0pt 36pt; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpMiddle"&gt;&lt;font color="#a6a6a6"&gt;&lt;span style="mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin; mso-themecolor: background1; mso-themeshade: 166"&gt;&lt;span style="mso-list: ignore"&gt;3.&lt;span style="line-height: normal; font-family: "&gt;&lt;font face="Times New Roman"&gt;&lt;font style="font-size: 7pt"&gt;       &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-themecolor: background1; mso-themeshade: 166"&gt;Mapping and Auto-Mapping Objects from XML&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="text-indent: -18pt; margin: 0cm 0cm 0pt 36pt; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpMiddle"&gt;&lt;font color="#a6a6a6"&gt;&lt;span style="mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin; mso-themecolor: background1; mso-themeshade: 166"&gt;&lt;span style="mso-list: ignore"&gt;4.&lt;span style="line-height: normal; font-family: "&gt;&lt;font face="Times New Roman"&gt;&lt;font style="font-size: 7pt"&gt;       &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-themecolor: background1; mso-themeshade: 166"&gt;Mapping and Auto-Mapping Objects from CSV &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="text-indent: -18pt; margin: 0cm 0cm 10pt 36pt; mso-list: l0 level1 lfo1" class="MsoListParagraphCxSpLast"&gt;&lt;font color="#a6a6a6"&gt;&lt;span style="mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin; mso-themecolor: background1; mso-themeshade: 166"&gt;&lt;span style="mso-list: ignore"&gt;5.&lt;span style="line-height: normal; font-family: "&gt;&lt;font face="Times New Roman"&gt;&lt;font style="font-size: 7pt"&gt;       &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-themecolor: background1; mso-themeshade: 166"&gt;Comparing Sixeyed.Mapping to AutoMapper&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;Enterprise projects typically have entities of the same kind defined multiple times to encapsulate different representations. A &lt;strong&gt;User&lt;/strong&gt; domain entity may be projected into a UserModel, containing a flattened subset of the User properties for display:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_thumb.png" border="0" height="292" width="506" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;With layers for domain entities, data contracts, service contract requests and responses, and presentation models you may have five definitions of a related entity, all of which are under your control, and all of which will (hopefully) have consistent naming conventions. Code to manually map between entity representations looks unnecessary as the source and target are so similar:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#2b91af"&gt;&lt;font style="font-size: 8pt"&gt;User&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; user = GetFullUser();&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#2b91af"&gt;&lt;font style="font-size: 8pt"&gt;UserModel&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; model = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;DateOfBirth = user.DateOfBirth,&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;FirstName = user.FirstName,&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Id = user.Id,&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;LastName = user.LastName&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//Intentionally leave out AddressLine1 for now&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;};&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;This is time-consuming, error-prone, and can add a huge maintenance overhead when properties are added or removed. Neater to use a generic auto-map, which matches properties between target and source entities, and populates target objects:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#2b91af"&gt;&lt;font style="font-size: 8pt"&gt;User&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; user = GetFullUser();&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; model = &lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;.CreateTarget(user);&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;a href="https://github.com/sixeyed/projects/tree/master/Sixeyed.Mapping"&gt;&lt;font color="#800080"&gt;Sixeyed.Mapping on github&lt;/font&gt;&lt;/a&gt; provides functionality for auto-mapping, and for creating static maps. (For an alternative, &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx"&gt;&lt;font color="#0000ff"&gt;Jimmy Bogard’sAutoMapper on CodePlex&lt;/font&gt;&lt;/a&gt;, is well established but it has a different approach. I wanted a consistent interface for auto maps and manual maps, the ability to map from different sources, and a smaller performance hit - see&lt;span style="mso-themecolor: background1; mso-themeshade: 166"&gt;&lt;font color="#a6a6a6"&gt; Comparing Sixeyed.Mapping to AutoMapper&lt;/font&gt;&lt;/span&gt;).&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal"&gt;Auto-Mapping&lt;/i&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;Auto-mapping is done at runtime, so when the entity definitions change there are no upstream code changes. AutoMap uses reflection, but the performance hit is relatively small and the map can be cached if it’s going to be used repeatedly. The example above is the simplest, but for cases which aren’t covered by discoverable mappings, you can specify individual property mapping actions:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; map = &lt;span&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;()&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;                &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;.Specify((s, t) =&amp;gt; t.AddressLine1 = s.Address.Line1) &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//flatten&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;                &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;.Specify((s, t) =&amp;gt; t.FirstName = s.FirstName.ToUpper()) &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//convert&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;                &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;.Specify((s, t) =&amp;gt; t.Address = &lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;Address&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;PartialAddress&lt;/font&gt;&lt;/span&gt;&amp;gt;.CreateTarget(s.Address)); &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//nested map&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt 36pt" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; model = map.Create(user);&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;Any properties not explicitly specified are auto-mapped. Mapping degrades gracefully, so any properties which can’t be mapped (either because the names can’t be matched, or the source cannot be read from, or the target cannot be written to) are not populated. (Optionally you can force exceptions to be thrown on mismatches).&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;AutoMap uses a naming strategy to match properties. By default this uses a simple matching algorithm, ignoring case and stripping non-alphanumeric characters. You can override the default to use exact name matching, aggressive name matching (which acts like the simple match but additionally strips vowels and double-letters), or to supply your own strategy (implementing &lt;b style="mso-bidi-font-weight: normal"&gt;IMatchingStrategy&lt;/b&gt;):&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; map = &lt;span&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;(); &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//matches "IsValid" and "IS_VALID"&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; exactMap = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;()&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: "&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt"&gt;.Matching&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;ExactNameMatchingStrategy&lt;/font&gt;&lt;/span&gt;&amp;gt;()&lt;/font&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt;; &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//matches "IsValid" and "IsValid"&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; aggressiveMap = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;()&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: "&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt"&gt;.Matching&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;AggressiveNameMatchingStrategy&lt;/font&gt;&lt;/span&gt;&amp;gt;()&lt;/font&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//matches "IsValid" and "ISVLD"&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; customMap = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;()&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt 36pt" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;                        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;.&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: "&gt;&lt;font style="font-size: 8pt"&gt;Matching&lt;/font&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;LegacyNameMatchingStrategy&lt;/font&gt;&lt;/span&gt;&amp;gt;(); &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//custom, matches "IsValid" and "bit_ISVALID"&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;Internally, AutoMap uses the naming strategy to generate a list of &lt;b style="mso-bidi-font-weight: normal"&gt;IPropertyMapping&lt;/b&gt; objects which represent maps between source and target properties. By default the list is only cached for the lifetime of the map, so the performance cost of reflecting over the types is incurred every time an AutoMap is instantiated and used. The justification for this is that the mapping cache will grow unknowably large, so a simple dictionary cache could end up with a large memory footprint. Equally the performance hit is small, and .NET uses internal caching for reflected types, so in subsequent generations of the same type of map the performance hit will be smaller.&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;AutoMap does provide a caching strategy if you do want the mappings cached. You can either use the internal cache (which is a simple dictionary and will never be flushed), the standard .NET runtime cache, or provide a wrapper over your own caching layer with an &lt;b style="mso-bidi-font-weight: normal"&gt;ICachingStrategy&lt;/b&gt; implementation:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; map = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;(); &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//mappings not cached&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; dictionaryMap = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;()&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;                             &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;.&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: "&gt;&lt;font style="font-size: 8pt"&gt;Cache&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;DictionaryCachingStrategy&lt;/font&gt;&lt;/span&gt;&amp;gt;(&lt;/font&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt;); &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//mappings cached in dictionary&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; cachedMap = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;()&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt;.&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: "&gt;&lt;font style="font-size: 8pt"&gt;Cache&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;MemoryCacheCachingStrategy&lt;/font&gt;&lt;/span&gt;&amp;gt;&lt;/font&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt;(); &lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//mappings cached in .NET runtime cache&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal"&gt; &lt;/i&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt; mso-outline-level: 1" class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal"&gt;Static Mapping&lt;/i&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;For complex maps, or for scenarios where you don’t want the reflection performance hit at all, you can define a static map. The interface is the same as AutoMap, except by default all properties have to be specified – there is no auto-mapping of unspecified targets, so additionally the naming and caching strategies are ignored.&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;Static object maps are derived from ClassMap, with the specifications made in the constructor (&lt;a href="http://fluentnhibernate.org/"&gt;&lt;font color="#0000ff"&gt;FluentNHibernate&lt;/font&gt;&lt;/a&gt;-style):&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;UserToUserModelMap&lt;/font&gt;&lt;/span&gt; : &lt;span&gt;&lt;font color="#2b91af"&gt;ClassMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="text-indent: 36pt; margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; UserToUserModelMap()&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;            &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify(s =&amp;gt; s.Id, t =&amp;gt; t.Id);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;            &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify(s =&amp;gt; s.FirstName, t =&amp;gt; t.FirstName);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;            &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify(s =&amp;gt; s.LastName, t =&amp;gt; t.LastName);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;            &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify((s, t) =&amp;gt; t.AddressLine1 = s.Address.Line1);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;            &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify((s, t) =&amp;gt; t.Address.PostCode = s.Address.PostCode.Code);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;There are various &lt;i style="mso-bidi-font-style: normal"&gt;Specify&lt;/i&gt; overloads, so you can specify mappings in an action, or specify source and target with funcs as you prefer. Execute the map in the same way by calling Create or Populate to map from the source instance to a target:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#2b91af"&gt;&lt;font style="font-size: 8pt"&gt;User&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; user = GetFullUser();&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt 36pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; map = &lt;span&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;UserToUserModelMap&lt;/font&gt;&lt;/span&gt;();&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt 36pt" class="MsoNormal"&gt;&lt;font face="Courier New"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font color="#2b91af"&gt;&lt;font style="font-size: 8pt"&gt;UserModel&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font style="font-size: 8pt"&gt; model = map.Create(user);&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;You can mix-and-match static and auto-mapping by setting &lt;i style="mso-bidi-font-style: normal"&gt;AutoMapUnspecifiedTargets&lt;/i&gt;, meaning that the auto-map will be used for any target properties which have not been explicitly specified:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;UserToUserModelMap&lt;/font&gt;&lt;/span&gt; : &lt;span&gt;&lt;font color="#2b91af"&gt;ClassMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; UserToUserModelMap()&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;            &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;AutoMapUnspecifiedTargets = &lt;span&gt;&lt;font color="#0000ff"&gt;true&lt;/font&gt;&lt;/span&gt;;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;            &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify((s, t) =&amp;gt; t.AddressLine1 = s.Address.Line1);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;            &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify((s, t) =&amp;gt; t.Address.PostCode = s.Address.PostCode.Code);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;        &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;This also allows your static map to leverage the naming and caching strategies of AutoMap.&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal"&gt;Nested Maps&lt;/i&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;AutoMap doesn’t traverse object graphs, it will only populate properties in the first-level object (except where you have specified a mapping for a child object). To populate full graphs you can use nested auto-maps or static maps, with one of the &lt;i style="mso-bidi-font-style: normal"&gt;Specify&lt;/i&gt; overloads to supply a conversion which invokes the map on the target property:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify((s, t) =&amp;gt; t.User = &lt;span&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;FullUserToPartialUserMap&lt;/font&gt;&lt;/span&gt;().Create(s.User));&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//or:&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify(s =&amp;gt; s.User, t =&amp;gt; t.User, c =&amp;gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;FullUserToPartialUserMap&lt;/font&gt;&lt;/span&gt;().Create(c));&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font style="font-size: 8pt" color="#008000"&gt;//or:&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="font-family: ; mso-no-proof: yes"&gt;&lt;font face="Courier New"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font style="font-size: 8pt"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt"&gt;Specify((s, t) =&amp;gt; t.User = &lt;span&gt;&lt;font color="#2b91af"&gt;AutoMap&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;User&lt;/font&gt;&lt;/span&gt;, &lt;span&gt;&lt;font color="#2b91af"&gt;UserModel&lt;/font&gt;&lt;/span&gt;&amp;gt;.CreateTarget(s.User));&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal"&gt;Performance&lt;/i&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;As always, the generic solution has a performance implication, although the mapping has had a couple of rounds of optimisation done to minimise the overhead. The highest-value AutoMap solution, which removes as much code and maintenance overhead as possible, has the highest impact. Populating 250,000 objects, the static AutoMap&amp;lt;&amp;gt;.CreateTarget() method takes 13 seconds, compared to 5 seconds for manually populating the targets.&lt;span style="mso-spacerun: yes"&gt;  &lt;/span&gt;Caching the map reduces the time to 8 seconds, and generating the map once and reusing it reduces it again to 7 seconds. Using a static map takes 6 seconds:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_thumb_1.png" border="0" height="119" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;In a more representative sample, mapping a single object, the disparity is not so pronounced. Manual and AutoMap versions take approximately the same time; in different test runs, one will be quicker than the other. The static map is consistently faster than manually populating the target object (what? Yes. Possibly due to the &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/08/09/making-reflection-fly-and-exploring-delegates.aspx"&gt;&lt;font color="#0000ff"&gt;hard-core reflection optimisation technique from Jon Skeet&lt;/font&gt;&lt;/a&gt;):&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_thumb_2.png" border="0" height="84" width="432" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;Up to 1,000 objects, the performance hit in using the AutoMap is negligible:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_thumb_3.png" border="0" height="288" width="477" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;Above 1,000 objects the cost is more pronounced:&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_10.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/EltonStoneman/Windows-Live-Writer/Mapping-and-Auto-Mapping-Objects_14768/image_thumb_4.png" border="0" height="288" width="477" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;Note that the effort in mapping is computational, not memory-bound, so in a higher-spec system the differences will be smaller.&lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;In a production system, adding 0.0x seconds to a service call involving a database lookup or a service call is likely to be acceptable, especially if the map is used for a single object, or the map can be reused – in which case the overhead will be 0.00x seconds. Likewise if you’re populating a single model for a view, it’s likely to be justifiable for the reduction in the solution’s technical debt. &lt;/p&gt;  &lt;p style="margin: 0cm 0cm 10pt" class="MsoNormal"&gt;In different scenarios, the computation of the AutoMap may be an unacceptable performance hit, in which case a static map at least isolates the mapping logic and provides some of the benefits, at a lower performance cost.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/EltonStoneman/aggbug/148232.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Elton Stoneman</dc:creator>
            <guid>http://geekswithblogs.net/EltonStoneman/archive/2012/01/03/mapping-and-auto-mapping-objects.aspx</guid>
            <pubDate>Tue, 03 Jan 2012 23:22:52 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/EltonStoneman/comments/148232.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/EltonStoneman/archive/2012/01/03/mapping-and-auto-mapping-objects.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/EltonStoneman/comments/commentRss/148232.aspx</wfw:commentRss>
        </item>
        <item>
            <title>FluentHtmlTextWriter</title>
            <link>http://geekswithblogs.net/EltonStoneman/archive/2009/09/10/fluenthtmltextwriter.aspx</link>
            <description>&lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-SIZE: 10pt"&gt;[Source: &lt;a href="http://geekswithblogs.net/EltonStoneman"&gt;http://geekswithblogs.net/EltonStoneman&lt;/a&gt;] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Keeping up the&lt;font style="BACKGROUND-COLOR: #ffffff"&gt; &lt;/font&gt;&lt;a href="http://geekswithblogs.net/EltonStoneman/Admin/EditPosts.aspx?catid=10643"&gt;fluent &lt;/a&gt;work, I've put together a fluent interface which wraps the framework &lt;strong&gt;HtmlTextWriter&lt;/strong&gt;. For ASP.NET MVC, this makes generating HTML in extension methods to &lt;strong&gt;HtmlHelper&lt;/strong&gt; safer than &lt;em&gt;string.Format()&lt;/em&gt; and more readable than &lt;strong&gt;HtmlTextWriter&lt;/strong&gt;: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Image(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;HtmlHelper&lt;/span&gt; helper, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; imageRelativeUrl, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; altText) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;FluentHtmlTextWriter&lt;/span&gt;.Begin() &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WriteTag(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Img) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Src, GetImageUrl(imageRelativeUrl)) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Alt, altText) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.End(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;The equivalent using &lt;strong&gt;HtmlTextWriter&lt;/strong&gt; is: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Image(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;HtmlHelper&lt;/span&gt; helper, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; imageRelativeUrl, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; altText) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: #2b91af"&gt;StringBuilder&lt;/span&gt; htmlBuilder = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;StringBuilder&lt;/span&gt;(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriter&lt;/span&gt; writer = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;HtmlTextWriter&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;StringWriter&lt;/span&gt;(htmlBuilder)); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;writer.AddAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Src, GetImageUrl(imageRelativeUrl)); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;writer.AddAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Alt, altText); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;writer.RenderBeginTag(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Img); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;writer.RenderEndTag(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;writer.Flush(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; htmlBuilder.ToString(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;Unlike the framework writer, you're not constrained to specify attributes in any particular order, and tags which aren't nested can be written with a single &lt;em&gt;WriteTag()&lt;/em&gt;, rather than &lt;em&gt;BeginTag()&lt;/em&gt; and &lt;em&gt;EndTag()&lt;/em&gt; calls. The writer copes with multi-level tag hierarchies - this sample builds a &lt;a href="http://users.tpg.com.au/j_birch/plugins/superfish/"&gt;Superfish&lt;/a&gt; CSS menu: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: #2b91af"&gt;FluentHtmlTextWriter&lt;/span&gt; writer = &lt;span style="COLOR: #2b91af"&gt;FluentHtmlTextWriter&lt;/span&gt;.Begin(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;writer.BeginTag(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Ul) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Id, &lt;span style="COLOR: #a31515"&gt;"menu.Name"&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="COLOR: #a31515"&gt;"sf-menu sf-vertical"&lt;/span&gt;); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.BeginTag(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Li) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.BeginTag(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.A) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="COLOR: #a31515"&gt;"sf-with-ul"&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Href, &lt;span style="COLOR: #a31515"&gt;"#"&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithValue(&lt;span style="COLOR: #a31515"&gt;"Link 1"&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WriteTag(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Span) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="COLOR: #a31515"&gt;"sf-sub-indicator"&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithValue(&lt;span style="COLOR: #a31515"&gt;"&amp;amp;#187;"&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.EndTag() &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.EndTag() &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.EndTag(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; html = writer.End(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="COLOR: #a31515"&gt;"&amp;lt;ul id=\"menu.Name\" class=\"sf-menu sf-vertical\"&amp;gt;\r\n\t&amp;lt;li&amp;gt;&amp;lt;a class=\"sf-with-ul\" href=\"#\"&amp;gt;Link 1&amp;lt;span class=\"sf-sub-indicator\"&amp;gt;&amp;amp;#187;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;\r\n&amp;lt;/ul&amp;gt;"&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;html);&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;HtmlTextWriter&lt;/strong&gt; equivalent is unthinkable. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://ondevelopment.blogspot.com/"&gt;Patrik Hägne&lt;/a&gt; has an alternative &lt;a href="http://ondevelopment.blogspot.com/2009/01/htmltextwriter-fluent-interface.html"&gt;fluent HtmlTextWriter&lt;/a&gt; implementation, which is nicely put together, but I wanted slightly different functionality. Firstly I wanted to get the HTML string from the writer directly, without needing to instantiate a &lt;strong&gt;StringBuilder&lt;/strong&gt; and &lt;strong&gt;StringWriter&lt;/strong&gt;. Secondly I wanted minimal new code – Patrik uses a separate class to manage writing attributes, and has specific functions for known tag types. Thirdly, I didn't really like Patrik's syntax, with the need to specify the tag type when you write an end tag – and when tags aren't nested, I wanted to write them in a single unit: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; html = &lt;span style="COLOR: #2b91af"&gt;FluentHtmlTextWriter&lt;/span&gt;.Begin() &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WriteTag(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Span) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithAttribute(&lt;span style="COLOR: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Id, &lt;span style="COLOR: #a31515"&gt;"id_span"&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.WithValue(&lt;span style="COLOR: #a31515"&gt;"contents_span"&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;.End(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="COLOR: #a31515"&gt;"&amp;lt;span id=\"id_span\"&amp;gt;contents_span&amp;lt;/span&amp;gt;"&lt;/span&gt;, html);&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;My version is on MSDN Code Gallery here: &lt;a href="http://code.msdn.microsoft.com/FluentHtmlTextWriter"&gt;FluentHtmlTextWriter&lt;/a&gt;. It works by building up a list of actions when you start writing a tag, and flushing them in the correct order to an internal &lt;strong&gt;HtmlTextWriter&lt;/strong&gt; when you start writing the next tag. When you call &lt;em&gt;End()&lt;/em&gt; it flushes the internal writer and outputs its contents. An alternative constructor lets you write directly to an output stream, in which case you can &lt;em&gt;Flush()&lt;/em&gt; the writer and don't need to call &lt;em&gt;End()&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;The current implementation only deals with basic tag, attribute and style functionality, and doesn't include optional HTML encoding overloads. It's only 75 lines of code, and extending it should be trivial. &lt;/p&gt;
&lt;p&gt;There is a negligible performance hit in using &lt;strong&gt;FluentHtmlTextWriter&lt;/strong&gt; – running the image tag generation code above 20,000 times on my dev machine, the fluent version takes between 0.01and 0.02 seconds longer than the framework version (on average 0.07 seconds compared to 0.05). &lt;/p&gt; &lt;img src="http://geekswithblogs.net/EltonStoneman/aggbug/134758.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>EltonStoneman</dc:creator>
            <guid>http://geekswithblogs.net/EltonStoneman/archive/2009/09/10/fluenthtmltextwriter.aspx</guid>
            <pubDate>Thu, 10 Sep 2009 18:32:28 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/EltonStoneman/comments/134758.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/EltonStoneman/archive/2009/09/10/fluenthtmltextwriter.aspx#feedback</comments>
            <slash:comments>13</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/EltonStoneman/comments/commentRss/134758.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Fluent DAL Mapping</title>
            <link>http://geekswithblogs.net/EltonStoneman/archive/2009/09/08/fluent-dal-mapping.aspx</link>
            <description>&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;If you spend some time using &lt;a href="http://fluentnhibernate.org/"&gt;Fluent NHibernate&lt;/a&gt;, you’ll want to use its neat style of mapping for all data access, even when you’re working against traditional DALs. I’ve put a sample up on MSDN Code Gallery for this scenario, using a fluent style of mapping between domain objects and data readers populated by stored procedure calls.&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;The interface is very similar to FNH, with a mapping class used for each domain entity – this is a simple mapping class:&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt"&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;PostCodeMap&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;DataReaderMap&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;PostCode&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; PostCodeMap()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;        Map(x =&amp;gt; x.InwardCode, &lt;span style="COLOR: #a31515"&gt;"PS_IN"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;        Map(x =&amp;gt; x.OutwardCode, &lt;span style="COLOR: #a31515"&gt;"PS_OUT"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;&lt;span style="FONT-SIZE: 10pt"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;The string constants define the column names expected in the data reader, and the base class takes care of running the map. For more complex entities, &lt;strong&gt;DataReaderMap&lt;/strong&gt; also includes mapping via a conversion function:&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;&lt;span style="FONT-SIZE: 10pt"&gt;    Map&amp;lt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt;&amp;gt;(x =&amp;gt; x.Activated, &lt;span style="COLOR: #a31515"&gt;"AccountActivated"&lt;/span&gt;, &lt;span style="COLOR: #2b91af"&gt;Legacy&lt;/span&gt;.FromBoolean);&lt;/span&gt;&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;- where the mapping specifies to and from types, and a delegate to invoke for the conversion (in this case, a method which converts a legacy string representation of a boolean – Y/N – to a bool).&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;For composite objects, the base map includes referencing, for cases where the child entity is loaded from the same data reader as the parent entity:&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;&lt;span style="FONT-SIZE: 10pt"&gt;    References(x =&amp;gt; x.Address, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;AddressMap&lt;/span&gt;());&lt;/span&gt;&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;Where the child entity is read from a separate data reader, then the composition needs to be done outside of the map in a repository or an assembler component. The &lt;strong&gt;Load&lt;/strong&gt; class isolates calling the stored procedure, so you get a fluent interface for populating domain objects, and collections of objects:&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt; GetUser(&lt;span style="COLOR: #2b91af"&gt;Guid&lt;/span&gt; userId)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;        &lt;span style="COLOR: green"&gt;//populate basic details:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;        &lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt; user = &lt;span style="COLOR: #2b91af"&gt;Fluently&lt;/span&gt;.Load&amp;lt;&lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt;&amp;gt;().With&amp;lt;&lt;span style="COLOR: #2b91af"&gt;UserMap&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;                            .From&amp;lt;&lt;span style="COLOR: #2b91af"&gt;GetUser&lt;/span&gt;&amp;gt;(i =&amp;gt; i.UserId = userId,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;                                           x =&amp;gt; x.Execute());&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;        &lt;span style="COLOR: green"&gt;//add accounts:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;        user.Accounts = &lt;span style="COLOR: #2b91af"&gt;Fluently&lt;/span&gt;.Load&amp;lt;&lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Account&lt;/span&gt;&amp;gt;&amp;gt;().With&amp;lt;&lt;span style="COLOR: #2b91af"&gt;AccountMap&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;                                .From&amp;lt;&lt;span style="COLOR: #2b91af"&gt;GetUserAccounts&lt;/span&gt;&amp;gt;(i =&amp;gt; i.UserId = userId,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;                                                       x =&amp;gt; x.Execute());&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt"&gt;        &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; user;&lt;/span&gt;&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;&lt;span style="FONT-SIZE: 10pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;The &lt;em&gt;From()&lt;/em&gt; call specifies the type of stored procedure, an action to populate the object, in this case setting up the &lt;em&gt;UserId&lt;/em&gt; parameter, and a function to call which returns a data reader, in this case &lt;em&gt;Execute().&lt;/em&gt;&lt;/div&gt;
&lt;div style="MARGIN: 0cm 0cm 10pt"&gt;The full sample is on the gallery here: &lt;a href="http://code.msdn.microsoft.com/FluentDALMapping"&gt;Fluent DAL Mapping&lt;/a&gt; . It’s a simple task to extend the sample to load datasets, or to populate update procedure calls from entities. If your database is sufficiently conventional this could be extended to provide FNH-style auto-mapping, reflecting over entities and using conventions to map properties to column names.&lt;/div&gt; &lt;img src="http://geekswithblogs.net/EltonStoneman/aggbug/134544.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>EltonStoneman</dc:creator>
            <guid>http://geekswithblogs.net/EltonStoneman/archive/2009/09/08/fluent-dal-mapping.aspx</guid>
            <pubDate>Tue, 08 Sep 2009 01:32:20 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/EltonStoneman/comments/134544.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/EltonStoneman/archive/2009/09/08/fluent-dal-mapping.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/EltonStoneman/comments/commentRss/134544.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>
