This is a bit of a long one, so get yourself a coffee (other quality libations are available).
In an effort to write as little code as possible, keep my apps simple, testable, maintainable and clean, and to turn apps around in quickly.
I'm using a really simple method I wrote to copy from MVC objects to EF objects to save me writing loads of code when I have objects with loads of properties. In fact, I don't care what the object is or how many properties it has. I just want to copy it without prepping loads of code in a map or somewhere.
Please don't start off on view models and all that, and quoting me the big book of Microsoft. All I'm looking for a little advice from my peers and the community in general about AutoMapper The example here is simple so you can see what I'm getting at.
What I didn't want to do and I've seen it lots, was:-
item ... //the original item populated from somewhere, MVC database, who cares, its got stuff in it
Item newItem = new Item();
newItem.prop1 = item.prop1;
newItem.prop2 = item.prop2;
newItem.prop3 = item.prop3;
newItem.prop4 = item.prop4;
//... you get the idea
or even this ...
Item newItem = new Item {
prop1 = item.prop1,
prop2 = item.prop2,
prop3 = item.prop3,
prop4 = item.prop4,
//... you get the idea
}
So I came up with this. A function called CopyObject that does excatly what I want it to do, so I don't have to care about any objects or how many properties it has, I write one line of code anywhere I need to that does all the work for me. See the example below
//show the item in a view, typically a bootstrap popup dialog
public IActionResult EditItem(int ID)
{
Item item = _dbContext.Items.Where(i => i.ID == ID).FirstOrDefault();
if (item == null)
item = new Item { ... property defaults ... };
return View(item);
}
//save the item from the view
[HttpPost]
public JsonResult EditItem(Item item)
{
Item newItem = _dbContext.Item.Where(i => item.ID).FirstOrDefault();
if (newItem == null)
{
newItem = newItem {... property defaults ... };
_dbContext.Items.Add(newItem);
}
//here is the fun part
CopyObject(item, newItem, ...ignore some properties);
_dbContext.SaveChanges();
return new JsonResult( new { result = "success", message = "Updated" });
}
CopyObject is my function, it does nothing clever except it uses reflection to copy properties from one object to another (EF)object without losing the connection to EF. CopyObject looks like this (below). I won't bore you with the implementation, but simply, it uses reflection to copy properties between any two objects.
At the moment it only copies from the top-level because that's all I need it to do right now, but it wouldn't be a massive stretch to get it to copy a hierarchy of stuff.
It doesn't actually care that the object types match, it doesn't care that the property types match. It only cares that if finds properties on each object with the same name, and it will then attempt to copy the values. You can also specify properties not to copy.
/// <summary>
/// Copies the values of the properties from one object to another object with the same properties if they exist.
/// This will try to copy from any two objects whether they are the same object type or not
/// </summary>
/// <param name="CopyFrom">The object to copy property data from</param>
/// <param name="CopyTo">The object to copy property data to</param>
/// <param name="DontCopy">A (string) list field names not to be copied</param>
/// <returns>True if at least one property was copied, otherwise false</returns>
public bool CopyObjects(object CopyFrom, object CopyTo, params string[] DontCopy) {...}
There is nothing wrong with my code it works perfectly fine just the way I need it to. I don't have any extra work to do when I start a new project no matter how many properties any of the objects have. I just import that
Anyway, because I'm not published or any kind of authority my code is getting frowned upon. I've been told AutoMapper can do the same thing but I can't seem to make it. I always get a disconnected object that I then have to do some tomfoolery to get it back into the EF and ultimately database.
So my question is. How do you acheive the same thing using Automapper without lots of code?. Remember my goal is not to have to write loads of code, in prep or in line.