Copy Properties From One Object To Another

by adrian vintu 3/27/2011 8:42:00 PM

Introduction

This article describes a method to automatically copy data from an object to another object with similar structures. This is similar to a deep_copy(source, destination) but with the possibility of returning a type that is different from the source.

Background

If you have worked with WCF services, you have noticed that versioning can lead to a lot of code duplication. My problem showed up when a service of version 2.0 was using almost the exact structures as in version 1.0 and I wanted to use the same service workflow code, but with different structures.

I needed a way to apply/convert values from one object to another so I created a method to automatically drill down the source object graph and copy the properties from one object to another. There are many ways to do this, but I designed a method that is generic enough and also leaves place for customization/fine tuning/hacking.

Basically, what I needed was the ability to do this automatically:

  service_version1.Customer.Name = service_version2.Customer.Name;
  service_version1.Customer.Address.Street = service_version2.Customer.Address.Street;
  //service_version1.Customer.Address.Zip = ? // Zip not available in service_version2, skipped

How to use

Although there are some gotchas, the basic usage is as follows.

Include files PropertiesCopier.cs and (optionally) PropertiesCopier.Checks.cs in your project.

Call PropertiesCopier.CopyProperties on your source and destination objects.

  PropertiesCopier.CopyProperties(sourceObject, destinationObject);
More...

Unloadable plugins

by adrian vintu 5/15/2008 10:13:00 PM

Creating a plugin architecture in .net is pretty easy. Unless you need to unload the plugins - AppDomain.Unload just does not work. Unfortunately I have found little help on this issue ~ google ~ so I decided to write this article.

A few basics:

1. .net uses application domains - kind of VM isolation in Java 

2. multiple app domains can exist into a single process 

3. code running in on app domain cannot directly access code/resources in another app domain - they are isolated.

4. code failures in one app domain cannot affect other app domains

5 . individual assemblies cannot be unloaded, only whole app domains


In our case we will use a process containing a main domain - the main application - and another one where to load/unload plugins. It should look like this:


The main domain contains standard assemblies - mscorlib, System, etc - plus our plugins.dll module - this is the main application.



We now create another app domain in our code using:

AppDomain appDomainPluginA = AppDomain.CreateDomain("appDomainPluginA");

The domains should look like this:

More...

Foreach Loop VS For Loop

by adrian vintu 4/23/2008 11:42:00 PM

What do you suppose happens when this piece of code is run? Please take notice that the secondary foreach loop is using the same dataset.

DataSet dsMain = GetMainDataset();

foreach (DataRow dr in dsMain.Tables[0].Rows)
{
    Console.WriteLine(dr["ID"] + " | " + dr["NAME"]);

    dsMain = GetSecondaryDataset();

    foreach (DataRow drSecondary in dsMain.Tables[0].Rows)
        Console.WriteLine(drSecondary["DETAIL"]);
}

Will it generate a run time error? Infinite loop? Half the results? Is the DataRow variable dr equal to drSecondary? Is dsMain the same all over the code?

And, of course, WHY?


Well, let's take it step by step.


We first step through the first foreach loop and notice the dsMain pointer is 15335436 - badly shown in the photos in the watch.


The dataset dsMain contains 2 columns: ID and NAME.


We step after the

dsMain = GetSecondaryDataset();

and see that the pointer has changed to 15400908 - the assignment was successful and we have a new dataset.


The dataset dsMain now contains one column called DETAIL.


At this point we can raise the question: what happens after this inner foreach finishes and the loop goes back to the outer one?

Will the outer foreach loop end because the rows of the dataset were run to the end by the inner foreach loop?

Will the outer foreach loop crash because 

Console.WriteLine(dr["ID"] + " | " + dr["NAME"]);

is looking for columns ID and NAME that don't exist in dsMain dataset - remember the previous step where dsMain became a new dataset, with only one column DETAIL?


In order to answer our question, we need to look at the disassembly.

 


Did you catch the idea? The foreach loops are not using direct pointer to the dataset dsMain rows collection, but rather pointers to the enumerator to the rows collection. And the enumerator enumerates through the collection regardless of what happens to the dsMain pointer.

So the answer is: the code will work fine, because foreach loops use the (pointers to the) enumerators of the rows collection, not pointers to the rows.

More...

About Adrian Vintu

Adrian Vintu I am a computer software professional lately designing and programming .NET and Android applications.
Send mail

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008 - 2012

Sign in