<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Alteridem Consulting &#187; .NET 1.x</title>
	<atom:link href="http://www.alteridem.net/category/net/net-1x/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alteridem.net</link>
	<description>Software by Design</description>
	<lastBuildDate>Thu, 02 Sep 2010 17:52:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Method to Copy Data Between Objects of Different Types</title>
		<link>http://www.alteridem.net/2008/07/09/method-to-copy-data-between-objects-of-different-types/</link>
		<comments>http://www.alteridem.net/2008/07/09/method-to-copy-data-between-objects-of-different-types/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 16:05:00 +0000</pubDate>
		<dc:creator>Robert Prouse</dc:creator>
				<category><![CDATA[.NET 1.x]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Tips'n'Tricks]]></category>

		<guid isPermaLink="false">http://www.alteridem.net/2008/07/09/method-to-copy-data-between-objects-of-different-types/</guid>
		<description><![CDATA[One thing that I find tiresome when using the various Model/View patterns is the constant copying of data between the model and the view. Too often, I find myself writing code like this to copy data between an ICustomer and an ICustomerView; // Copy the data from the customer to the view view.Address = customer.Address; [...]]]></description>
			<content:encoded><![CDATA[<p>One thing that I find tiresome when using the various <a href="http://polymorphicpodcast.com/shows/mv-patterns/">Model/View patterns</a> is the constant copying of data between the model and the view. Too often, I find myself writing code like this to copy data between an <strong>ICustomer</strong> and an <strong>ICustomerView</strong>;</p>
<p><a name="listing1"></a></p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2ee7dfba-ed37-4b8e-9881-03d732dd1547" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter">// Copy the data from the customer to the view
view.Address = customer.Address;
view.Country = customer.Country;
view.FirstName = customer.FirstName;
view.LastName = customer.LastName;
view.PostalCode = customer.PostalCode;
view.Province = customer.Province;</pre>
</div>
<p>I would much rather write something like one of the following lines;</p>
<p><a name="listing2"></a></p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d4534127-22e3-47de-9638-6bc33333d17b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">// Copy the data from the customer to the view (using reflection in .NET 1.x)
CopyHelper.Copy( typeof(ICustomer), customer, typeof(ICustomerView), view );

// Copy the data from the customer to the view (using reflection and generics in .NET 2.0)
Copier&lt;ICustomer&gt;.Copy( customer ).To&lt;ICustomerView&gt;( view );

// Copy the data from the customer to the view (using extension methods in C# 3.0)
customer.CopyTo&lt;ICustomerView&gt;( view );</pre>
</div>
<p>It got me to thinking that there must be a better way, so I began writing code that would do the grunt work for me. Too often,</p>
<p>Over the next few days, I will blog about my thought process in developing this method and take it through the various iterations that can be seen in lines 2, 5 &amp; 8 above.</p>
<p>Today, I will start with the .NET 1.x version. I will start with some design decisions;</p>
<ul>
<li>I want to be able to specify the types that I am copying between, not infer them using reflection. This way, I can use the interfaces, not the concrete classes when I am copying between the objects. </li>
<li>For now, I am going to assume that if both interfaces have a non-static get/set property with the same <strong>name</strong> and <strong>type</strong> I will copy between them. </li>
<li>I need to check that neither object is null and that I am not trying to copy an object over to itself. </li>
</ul>
<p>This was simple enough. I created a static helper class called <strong>CopyHelper</strong> with one static <strong>Copy</strong> method. I use <a href="http://msdn.microsoft.com/en-us/library/kyaxdd3x.aspx">Type.GetProperties</a> to get the non-static, public properties with getters and setters. If the name and type match, I use the <a href="http://msdn.microsoft.com/en-us/library/b05d59ty.aspx">GetValue</a> and <a href="http://msdn.microsoft.com/en-us/library/xb5dd1f1.aspx">SetValue</a> methods on the <a href="http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.aspx">PropertyInfo</a> class to copy the value across from one object to the next. This is the result;</p>
<p><a name="listing3"></a></p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c3141718-afd0-45c0-af12-a896a062b949" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">#region Copyright © Alteridem Consulting 2008
//
// All rights are reserved. Reproduction or transmission in whole or in part, in
// any form or by any means, electronic, mechanical or otherwise, is prohibited
// without the prior written consent of the copyright owner.
//
// Filename: CopyHelper.cs
// Date:     06/06/2008 11:18 AM
// Author:   Rob Prouse
//
#endregion

#region Using Directives

using System;
using System.Collections.Generic;
using System.Reflection;

#endregion

namespace Alteridem.ModelViewHelpers
{
    public static class CopyHelper
    {
        #region Private Members

        // We are interested in non-static, public properties with getters and setters
        private const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty;

        #endregion

        /// &lt;summary&gt;
        /// Copies all public properties from one object to another.
        /// &lt;/summary&gt;
        /// &lt;param name="fromType"&gt;The type of the from object, preferably an interface. We could infer this using reflection, but this allows us to contrain the copy to an interface.&lt;/param&gt;
        /// &lt;param name="from"&gt;The object to copy from&lt;/param&gt;
        /// &lt;param name="toType"&gt;The type of the to object, preferably an interface. We could infer this using reflection, but this allows us to contrain the copy to an interface.&lt;/param&gt;
        /// &lt;param name="to"&gt;The object to copy to&lt;/param&gt;
        public static void Copy( Type fromType, object from, Type toType, object to )
        {
            if ( fromType == null )
                throw new ArgumentNullException( "fromType", "The type that you are copying from cannot be null" );

            if ( from == null )
                throw new ArgumentNullException( "from", "The object you are copying from cannot be null" );

            if ( toType == null )
                throw new ArgumentNullException( "toType", "The type that you are copying to cannot be null" );

            if ( to == null )
                throw new ArgumentNullException( "to", "The object you are copying to cannot be null" );

            // Don't copy if they are the same object
            if ( !ReferenceEquals( from, to ) )
            {
                // Get all of the public properties in the toType with getters and setters
                Dictionary&lt;string, PropertyInfo&gt; toProperties = new Dictionary&lt;string, PropertyInfo&gt;();
                PropertyInfo[] properties = toType.GetProperties( flags );
                foreach ( PropertyInfo property in properties )
                {
                    toProperties.Add( property.Name, property );
                }

                // Now get all of the public properties in the fromType with getters and setters
                properties = fromType.GetProperties( flags );
                foreach ( PropertyInfo fromProperty in properties )
                {
                    // If a property matches in name and type, copy across
                    if ( toProperties.ContainsKey( fromProperty.Name ) )
                    {
                        PropertyInfo toProperty = toProperties[fromProperty.Name];
                        if ( toProperty.PropertyType == fromProperty.PropertyType )
                        {
                            object value = fromProperty.GetValue( from, null );
                            toProperty.SetValue( to, value, null );
                        }
                    }
                }
            }
        }
    }
}</pre>
</div>
<p>Using this <a href="#listing3">class</a>, you can now write code like in <a href="#listing2">line 2 of the second listing</a> above. In my <a href="http://www.alteridem.net/2008/07/21/extending-copyhelper-using-generics/">next post</a>, I am going to extend this code using generics and give it a <a href="http://en.wikipedia.org/wiki/Fluent_interface">fluent interface</a> for better readability.</p>
<p>I am very interested in hearing your feedback on this, so be sure to post to the comments. Do you think this is a good idea? Do you have suggestions for improvements? Let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alteridem.net/2008/07/09/method-to-copy-data-between-objects-of-different-types/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
