Object Mapping Error - c#

My First Model in WCF
public class One
{
public string A { get; set; }
public string B { get; set; }
}
My Second
public class Two : One
{
public string C { get; set; }
}
Now I have Value for the properties of Model Two like this
Two obj = new Two()
{
A="ww",
B="WWW",
C="EE"
};
One obj1 = new One();
Now i want to copy my obj object value to obj1.
But i need to skip the third value while copying in first object ..How To do it?

You can create a copy constructor for One:
public class One
{
public One(One other)
{
A = other.A;
B = other.B;
}
public string A { get; set; }
public string B { get; set; }
}
And use it like this:
Two two = new Two
{
A="ww",
B="WWW",
C="EE"
};
One one = new One(two);

Related

Assigning data from a class list to another class list

I have the following class which is populated after de-serializing a JSON string:
public class Doors
{
public List<Door> doors { get; set; }
}
public class Door
{
public int id { get; set; }
public string name { get; set; }
public bool elevator { get; set; }
}
JSON string:
var result = JsonConvert.DeserializeObject<Doors>(response.Content);
// "{\"doors\":[{\"id\":1,\"name\":\"Main Door\",\"elevator\":false},{\"id\":2,\"name\":\"Back Door\",\"elevator\":false}]}"
The data maps to my class fine, I'm then trying to pass the class data to another class:
public class WS4APIResult
{
public List<Door> doors { get; set; } = new List<Door>();
}
public class Door
{
public int id { get; set; }
public string name { get; set; }
public bool elevator { get; set; }
}
return new WS4APIResult() {
doors = result.doors
}
With the following error: any ideas please?
Cannot implicitly convert type 'System.Collections.Generic.List<WS4PortalApi.Models.Door>' to 'System.Collections.Generic.List<WS4PortalApi.Domain.Door>'
The two c#-Files refer to different classes if you type Door. You need to implement a conversion between WS4PortalApi.Models.Door and WS4PortalApi.Domain.Door.
Like:
public static WS4PortalApi.Domain.Door DoorConvert(WS4PortalApi.Models.Door door)
then you can use linq to generate a new List
doors = result.doors
.Select(d => DoorConvert(d))
.ToList();
You have to map the properties of your domain object to those of the model.
I normally create a method for this like:
var doors = new List<Model.Door>();
foreach(door in result.doors)
{
var doorModel = new Model.Door
{
id = door.id,
name = door.name,
elevator = door.elevator
};
doors.Add(doorModel);
}
return doors;
Or you can use a library like automapper.

How to handle same code parts in Factory Method?

I reposted question on codereview but can not delete this question couse already answer here.
I have some classes:
public abstract class House
{
public string Name { set; get;}
public SomeClass Property1 { set; get;}
public OtherClass Property2 { set; get;}
}
public class WoodenHouse:House
{
public string WoodType { set; get;}
public int WoodAge { set; get;}
}
public class StoneHouse:House
{
public string StoneType { set; get;}
}
And trying to create Factory Method pattern for this:
abstract class Creator
{
public abstract HouseInfo Info { get; set; }
public Creator()
{
}
public abstract House FactoryMethod();
}
class WoodenHouseCreator : Creator
{
public override HouseInfo Info { get; set; }
public WoodenHouseCreator(WoodenHouseInfo info)
{
Info = info;
}
public override House FactoryMethod()
{
var info = Info as WoodenHouseInfo;
var woodenHouse = new WoodenHouse();
woodenHouse.Name = info.Name;
woodenHouse.Floors = info.Floors;
woodenHouse.RoofType = info.RoofType;
woodenHouse.WoodType = info.WoodType;
woodenHouse.WoodAge = info.WoodAge;
return woodenHouse;
}
}
class StoneHouseCreator : Creator
{
public override HouseInfo Info { get; set; }
public StoneHouseCreator(StoneHouseInfo info)
{
Info = info;
}
public override House FactoryMethod()
{
var info = Info as StoneHouseInfo;
var stoneHouse = new StoneHouse();
stoneHouse.Name = info.Name;
stoneHouse.Floors = info.Floors;
stoneHouse.RoofType = info.RoofType;
stoneHouse.StoneType = info.StoneType;
return stoneHouse;
}
}
Here are the classes what contain information to create ahouse:
class HouseInfo
{
public string Name { set; get; }
public int Floors { set; get; }
public string RoofType { set; get; }
}
class WoodenHouseInfo : HouseInfo
{
public string WoodType { set; get; }
public int WoodAge { set; get; }
}
class StoneHouseInfo : HouseInfo
{
public string StoneType { set; get; }
}
And Usage:
var houseInfo = new WoodenHouseInfo
{
Name = "HouseName",
Floors = 2,
RoofType = "Triangle",
WoodType = "Pine",
WoodAge = 100
};
House house;
if(houseInfo is WoodenHouseInfo)
{
var creator = new WoodenHouseCreator(houseInfo);
house = creator.FactoryMethod();
Console.Write((house as WoodenHouse).WoodAge);
}
Full code fiddle.
My problem is how to handle code duplication. I mean there is a lot of lines that fills base House object properties. How can I write that code only once?
Or I should not to use Factory Method?
Currently your factories instantiate the new objects and then fill in all of their properties with the right values. You could split instantiation from property value assignment. Your StoneHouseCreator could instantiate a StoneHouse, use a HousePopulator that populates the values that all objects of type House have in common, and then the StoneHouseCreator could populate the rest of the values that are exclusive to a StoneHouse. That same HousePopulator could also be used by your WoodenHouseCreator, which would then proceed to populate the WoodenHouse-specific properties.
If you want to philosophise about this at a higher level, these are the problems that we run into because of inheritance. Factories, that is the logical separation of object use from object creation, are more naturally suited to cases where you use composition over inheritance. If you are interested more in this, I would recommend reading this excellent article on the topic.

How to go about combining two objects, manipulate the data, then separate them?

I have two classes with some similar fields, some different, and a form that utilizes two different objects depending on what mode it's in (insert/edit).
Instead of using two different objects and if statements checking the form mode, I'd like to have one struct to be hydrated with either of the two objects fields so I can manipulate one object through the page life-cycle. Then separated the struct back to its respective object for insert/updating the DB.
Example of classes:
public partial class SomeClass
{
public Int32 B {get;set;}
public String C {get;set;}
public Boolean D {get;set;}
}
public class SomeOtherClass
{
public Int32 A {get;set;}
public Int32 B {get;set;}
public String C {get;set;}
}
Update with Solution Example:
public interface IInsertable
{
string SharedName { get; set; }
string SharedID { get; set; }
string editedFieldValue { get; set; }
long GetSuperSecreteInfo();
}
internal class InsertableImplementation : IInsertable
{
public string SharedName { get; set; }
public string SharedID { get; set; }
public string editedFieldValue { get; set; }
public long GetSuperSecreteInfo()
{
return -1;
}
}
public interface IUpdateable
{
string SharedName { get; set; }
string SharedID { get; set; }
string updatedFieldValue { get; set; }
Guid GenerateStevesMagicGuid();
}
internal class UpdateableImplementation : IUpdateable
{
public string SharedName { get; set; }
public string SharedID { get; set; }
public string updatedFieldValue { get; set; }
public Guid GenerateStevesMagicGuid()
{
return new Guid();
}
}
public static class WonderTwinFactory
{
public static WonderTwins GenerateWonderTwin(IUpdateable updateable, IInsertable insertable)
{
var wt = new WonderTwins();
// who will win?
wt.SharedID = updateable.SharedID;
wt.SharedID = insertable.SharedID;
// you decide?
wt.SharedName = updateable.SharedName;
wt.editedFieldValue = "stuff";
return wt;
}
}
public class WonderTwins : IInsertable, IUpdateable
{
public string SharedName { get; set; }
public string SharedID { get; set; }
public string editedFieldValue { get; set; }
public long GetSuperSecreteInfo()
{
return 1;
}
public string updatedFieldValue { get; set; }
public Guid GenerateStevesMagicGuid()
{
return new Guid();
}
}
class Program
{
static void Main(string[] args)
{
IUpdateable updateable = new UpdateableImplementation();
IInsertable insertable = new InsertableImplementation();
WonderTwins dualImplementatin = WonderTwinFactory.GenerateWonderTwin(updateable, insertable);
IUpdateable newUpdateable = dualImplementatin as IUpdateable;
IInsertable newInsertable = dualImplementatin as IInsertable;
}
}
Have both classes implement an interface that defines the operations common to each, including both the fields that are shared (assuming the view needs to access them) and also a method to actually perform the operation that they represent (insert/edit).
Other way of doing such things is using C# dynamic object and assign properties directly. It may help to avoid any new type or interface and directly utilizing new dynamic object any time, as much as required.
var newObject = new {
objectOfClass1 = x.prop1,
objectOfClass2 = x.prop2
}

AutoMapper - Map a complex object using naming conventions without providing inner mappings

I have two complex objects that have exactly the same properties.
Now with AutoMapper, I usually will need to do something like this:
Mapper.CreateMap<ObjA, ObjB>();
But if one of the objects has a complex inner object, Ill need to map it too:
Mapper.CreateMap<ObjAInner, ObjBInner>();
Now I have a large object that expands all the time.
I don't want to maintain the CreateMap calls each time I add a complex inner object to the main object.
Now I can probably solve this with a recursive reflection on the main object and map all the types but I'd prefer not to do that.
Is there anyway I can tell AutoMapper to Create a full recursive map(also for inner types) on a complex object?
Something like this:
Mapper.CreateFullMapOnIdenticalObjectsWithInnerTypes<ObjA, ObjB>();
Edit:
Here's an example:
two identical classes with a different namespace:
namespace NameSpace1
{
public class Obj1
{
public string Str { get; set; }
public int Num { get; set; }
public InnerObj1 InnerObj1 { get; set; }
}
public class InnerObj1
{
public string StrInner1 { get; set; }
public int NumInner1 { get; set; }
public AnotherInnerObj1 AnotherInnerObj1 { get; set; }
}
public class AnotherInnerObj1
{
public string Str { get; set; }
}
}
namespace NameSpace2
{
public class Obj1
{
public string Str { get; set; }
public int Num { get; set; }
public InnerObj1 InnerObj1 { get; set; }
}
public class InnerObj1
{
public string StrInner1 { get; set; }
public int NumInner1 { get; set; }
public AnotherInnerObj1 AnotherInnerObj1 { get; set; }
}
public class AnotherInnerObj1
{
public string Str { get; set; }
}
}
Create a mock NameSpace1.Obj1:
public static NameSpace1.Obj1 Create()
{
return new NameSpace1.Obj1
{
Num = 10,
Str = "Obj1",
InnerObj1 = new NameSpace1.InnerObj1
{
NumInner1 = 11,
StrInner1 = "InnerObj1",
AnotherInnerObj1 = new NameSpace1.AnotherInnerObj1
{
Str = "AnotherInnerObj1"
}
}
};
}
This is what I would like:
Mapper.CreateMap<NameSpace1.Obj1, NameSpace2.Obj1>();
var obj1 = Create();
var obj2 = Mapper.Map<NameSpace2.Obj1>(obj1);
But this will throw an exception since I need to define inner mappings. This will work:
Mapper.CreateMap<NameSpace1.Obj1, NameSpace2.Obj1>();
Mapper.CreateMap<NameSpace1.InnerObj1, NameSpace2.InnerObj1>();
Mapper.CreateMap<NameSpace1.AnotherInnerObj1, NameSpace2.AnotherInnerObj1>();
var obj1 = Create();
var obj2 = Mapper.Map<NameSpace2.Obj1>(obj1);

Including a List<SpecificType> in a model, and how to populate it

I currently have three Model classes:
public class MarketReport
{
public MarketReportAbbrStores LISTOFSTORESUMMARY {get; set;}
}
public class MarketReportAbbrStores : List<AbbrStore>
{
public AbbrStore abbrStore { get; set; }
}
public class AbbrStore
{
public string StoreName { get; set; }
public int MemberCount { get; set; }
public int LeaderCount { get; set; }
public int ActivistCount { get; set; }
}
Now, I have no idea if I am doing the above correctly, but I want to populate the list within the MarketReport
foreach (var store in stores)
{
AbbrStore abbrstore = new AbbrStore();
abbrstore.StoreName = store;
marketInformation.LISTOFSTORESUMMARY.Add(abbrstore);
//ERROR: Object reference not set to an instance of an object.
}
Several things wrong here:
Your Leaders type is a List of itself - this shouldn't be a collection type because it's describing a single entity, so just Leader
leaderlist should use PascalCase - Leaders
leaderlist is an instance property, so you would need to instantiate a MarketReport to start to populate that list
leaderlist should be a List<Leader> if you don't have a collection type defined (see 1)
List<T> has an Add method which you should use to add new instances of Leader
You will need to instantiate a new list and assign it to the Leaders property before you can start adding to it
Suggested changes:
public class Leader
{
public string Name { get; set; }
public string Precinct { get; set; }
}
public class MarketReport
{
public List<Leader> Leaders { get; set }
}
this.Leaders = new List<Leader>();
foreach (var store in stores)
{
var leader = new Leader { ... };
this.Leaders.Add(leader);
}

Categories