How to clone an unserializable object? (C#) - c#

I am working with Kinect for Windows version 2 and meet a problem. I try to serialize the Body object and send it through the Internet. However Body object is not sterilisable. Although I can extract some key information from a Body object and create my own object, I may lose some information. My question is how to clone all information from a Body object to my own serializable object?
Thank you.

If cloning is what you're concerned with, use AutoMapper.
First you'll need to install AutoMapper using NuGet...
PM> Install-Package AutoMapper
Then check out this example and adapt it to your own needs...
void Main()
{
AutoMapper.Mapper.CreateMap<User, MyUser>()
.ForMember(myUsers => myUsers.Name, users => users.MapFrom(property => string.Format("{0} {1}",property.FirstName, property.LastName)));
User user = new User
{
FirstName = "James",
LastName = "Doe",
DateOfBirth = DateTime.UtcNow
};
MyUser myUser = AutoMapper.Mapper.Map<MyUser>(user);
}
public class MyUser
{
public string Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class User
{
public User()
{
this.Id = Guid.NewGuid().ToString();
}
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
In the example above, AutoMapper figures out that it can map the Id property of MyUser and User class because they're named identically, however we needed to create a custom map to map User.FirstName and User.LastName to MyUser.Name property.

If the purpose of serialization is to reconstruct it at the other end, the first thing you need to determine whether the constructor and setters exist for you to create an equivalent on the other side. If it is purely for an independent representation that your server side needs to interact with, you have a much simpler task.
My recommendation would be to inspect the body object both via the public interface available through documentation and via reflection in the debugger to determine what data you can and want to extract and build a custom, serializable class based on that hierarchical model.
If all the data you need to extract is publicly accessible, simply writer a builder class that takes the body object as its input and constructs your custom class as the output. If it's not publicly accessible, you may need to use reflection to explore the pieces you need. I would advise the reflection code to be manually built as to avoid cycles in the object graph that may exist in a private class as this.

It's alright. Just do the following logic:
Use reflection to loop through the properties of the object you wanna clone.
You can setup the data with your predefined custom class. (Perhaps you might want to generate the XML schema according to the object's properties and from there you create your own predefined custom class).
Hope this concept helps. If not, let's discuss further.

Related

Update all Fields passed in object without using replace

I'm writing a wrapper around certain functions of mongodb to enforce certain buisiness policies (such as having a last modified date, a document version &c). These extra fields will not appear in the model and will be irrelevant and transparent to the person implementing against this library. This library will be generic.
Therefore using replaceOne is out of the question.
What I would like is some way of passing all fields in a person passed object to the Update builder - so I can use .Set/.Inc accordingly to add the other fields.
An example to demonstrate what I want is below:
public static async Task UpdatePerson(string name, Person person)
{
var client = new MongoClient("mongodb://localhost:27017");
IMongoDatabase db = client.GetDatabase("test");
IMongoCollection<Person> collection = db.GetCollection<Person>("people");
var query = Builders<Person>.Filter
.Eq("name", name);
var update = Builders<Person>.Update
//Something here - how do I pass my person's properties?
.Set("lastModified", DateTime.Now)
.Inc("version",1);
await collection.UpdateOneAsync(query, update );
}
//--
//In real life this'll work for other types, this is for demonstration only
public class Person
{
public string name {get;set;}
public string surname {get;set;}
}
So how can I go about this, without, for instance, looping through properties using Reflection?
Not sure if you are able to do this but the Mongodb Driver provides something called [BsonExtraElements].
public class Person
{
public string name {get;set;}
public string surname {get;set;}
[BsonExtraElements]
public Dictionary<string,object> AdditionalFields { get; set; }
}
What will happen is that anything that cant be serialized to the model will be filled into that dictionary, no matter the type. You can add to it as well and remove.
This will add no additional overhead to your database, The only downside to this is that querying this dictionary is somewhat not a great experience as you may need to cast specific keys to their relevant expected types.
If this is not viable I suggest the BSON approach recommended by Simon.

Deserializing Json into objects

So the app I'm currently working with is going to be doing a lot of requests that all return json, would it be appropriate to create a class that holds the properties for each specific request thats going to return the json that can be converted into the properties of that class?
For example, say I have 2 requests, one that returns a firstname, a surname and a job role, and I have another request that returns a business name, business location and business postcode, would it be OK to do:
class BusinessRetrieval {
public string BusinessLocation{ get; set; }
public string BusinessPostCode { get; set; }
}
class EmployeeRetrieval {
public string Firstname { get; set; }
public string Surname { get; set;}
public string Postcode { get; set; }
}
So now I have 2 classes that outline the properties that are going to be sent back once the request is made, now is it OK to just do:
BusinessRetrieval business = (BusinessRetrieval)JsonConvert.DeserializeObject(businessResponse, typeof(BusinessRetrieval));
EmployeeRetrieval employee = (EmployeeRetrieval)JsonConvert.DeserializeObject(employeeResponse, typeof(EmployeeRetrieval));
What I'm asking here is this an OK to go around doing this? I'm going to be dealing with a lot of requests (10-15) and I plan on making a class for each that outline the properties that each response will give back, I feel as if this would be a nice way to structure it.
Is this OK?
Yes it is the only reasonable way to handle it to make your code type safe.
Though you cannot cast the result of the non generic DeserializeObject to the type of your choice - it will throw an Exception.
Instead use the Generic version of DeserializeObject:
BusinessRetrieval business = JsonConvert.DeserializeObject<BusinessRetrieval>(businessResponse);
EmployeeRetrieval employee = JsonConvert.DeserializeObject<EmployeeRetrieval>(employeeResponse);
I think it is not only okay to do, I think it would be a best practice so you can pass that object through any methods without any problems.

C# Comparing complex objects returning list of differences

I've been working on a project for a while to parse a list of entries from a csv file and use that data to update a database.
For each entry I create a new user instance that I put in a collection. Now I want to iterate that collection and compare the user entry to the user from the database (if it exists). My question is, how can I compare that user (entry) object to the user (db) object, while returning a list with differences?
For example following classes generated from database:
public class User
{
public int ID { get; set; }
public string EmployeeNumber { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<int> OfficeID { get; set; }
public virtual Office Office { get; set; }
}
public class Office
{
public int ID { get; set; }
public string Code { get; set; }
public virtual ICollection<User> Users { get; set; }
}
To save some queries to the database, I only fill the properties that I can retrieve from the csv file, so the ID's (for example) are not available for the equality check.
Is there any way to compare these objects without defining a rule for each property and returning a list of properties that are modified? I know this question seems similar to some earlier posts. I've read a lot of them but as I'm rather inexperienced at programming, I'd appreciate some advice.
From what I've gathered from what I've read, should I be combining 'comparing properties generically' with 'ignoring properties using data annotations' and 'returning a list of CompareResults'?
There are several approaches that you can solve this:
Approach #1 is to create separate DTO-style classes for the contents of the CSV files. Though this involves creating new classes with a lot of similar fields, it decouples the CSV file format from your database and gives you the ability to change them later without influencing the other part. In order to implement the comparison, you could create a Comparer class. As long as the classes are almost identical, the comparison can get all the properties from the DTO class and implement the comparison dynamically (e.g. by creating and evaluating a Lambda expression that contains a BinaryExpression of type Equal).
Approach #2 avoids the DTOs, but uses attributes to mark the properties that are part of the comparison. You'd need to create a custom attribute that you assign to the properties in question. In the compare, you analyze all the properties of the class and filter out the ones that are marked with the attribute. For the comparison of the properties you can use the same approach as in #1. Downside of this approach is that you couple the comparison logic tightly with the data classes. If you'd need to implement several different comparisons, you'd clutter the data classes with the attributes.
Of course, #1 results in a higher effort than #2. I understand that it is not what you are looking for, but maybe having a separate, strongly-typed compared class is also an approach one can think about.
Some more details on a dynamic comparison algorithm: it is based on reflection to get the properties that need to be compared (depending on the approach you get the properties of the DTO or the relevant ones of the data class). Once you have the properties (in case of DTOs, the properties should have the same name and data type), you can create a LamdaExpression and compile and evaluate it dynamically. The following lines show an excerpt of a code sample:
public static bool AreEqual<TDTO, TDATA>(TDTO dto, TDATA data)
{
foreach(var prop in typeof(TDTO).GetProperties())
{
var dataProp = typeof(TDATA).GetProperty(prop.Name);
if (dataProp == null)
throw new InvalidOperationException(string.Format("Property {0} is missing in data class.", prop.Name));
var compExpr = GetComparisonExpression(prop, dataProp);
var del = compExpr.Compile();
if (!(bool)del.DynamicInvoke(dto, data))
return false;
}
return true;
}
private static LambdaExpression GetComparisonExpression(PropertyInfo dtoProp, PropertyInfo dataProp)
{
var dtoParam = Expression.Parameter(dtoProp.DeclaringType, "dto");
var dataParam = Expression.Parameter(dataProp.DeclaringType, "data");
return Expression.Lambda(
Expression.MakeBinary(ExpressionType.Equal,
Expression.MakeMemberAccess(
dtoParam, dtoProp),
Expression.MakeMemberAccess(
dataParam, dataProp)), dtoParam, dataParam);
}
For the full sample, see this link. Please note that this dynamic approach is just an easy implementation that leaves room for improvement (e.g. there is no check for the data type of the properties). It also does only check for equality and does not collect the properties that are not equal; but that should be easy to transfer.
While the dynamic approach is easy to implement, the risk for runtime errors is bigger than in a strongly-typed approach.

Good class design by example

I am trying to work out the best way to design a class that has its properties persisted in a database. Let's take a basic example of a Person. To create a new person and place it in the database, I want the DateOfBirth property to be optional (i.e. NULLable in the DB).
Here's my sample code:
namespace BusinessLayer
{
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
}
I'm unsure as to whether the fields should be public or not. Should I do it like this:
class Program
{
static void Main(string[] args)
{
Person person1 = new Person("Kate","Middleton",null);
}
}
or like this:
class Program
{
static void Main(string[] args)
{
Person person1 = new Person();
person1.FirstName = "Kate";
person1.LastName = "Middleton";
}
}
I'm also wondering how I should be dealing with the optional properties of the class. Once the fields have been populated how do I then save them to the DB? I have a DatabaseComponenet class to save the information. How do I deal with the optional when saving to the database?
So, would I do something like this:
public int Save()
{
int personId;
personId = DatabaseComponent.InsertPerson(FirstName, LastName, DateOfBirth);
return personId;
}
Thanks for any help! Some useful URLs on good class design would also be appreciated.
First, I'd put two distinct public constructor to Person:
namespace BusinessLayer
{
class Person
{
public Person(string firstName, string lastName): this(firstName, lastName, DateTime.Now)
{}
public Person(string firstName, string lastName, DateTime birthDate)
{
FirstName = firstName;
LastName = lastName;
DateOfBirth = birthDate;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
}
this allows you to write both
var p = new Person("Marilyin", "Manson");
var p2 = new Person("Alice", "Cooper", new DateTime(...));
and
var p = new Person { FirstName="Marilyn", LastName="Manson" };
I can't see why you should limit to only one form.
As for the DatabaseComponent I'd strongly suggest to write a method that allows you to save a Person instead of the signature you are implicitly declaring.
That's because, should one day change the way a Person is defined, you'd probably have to change the code in each point you invoke Save() method. By saving just a Person, you only have to change the Save() implementation.
Don't you plan to use an ORM by the way?
With C# 3.0 class initializers I no longer bother of providing a constructor that allows me to initialize all properties:
var person1 = new Person
{
FirstName = "Kate";
LastName = "Middleton";
};
As far as the Save method is concerned I usually put them in a separate repository class:
public int Save(Person person)
{
...
}
and then when I need to save a person I do:
var person1 = new Person
{
FirstName = "Kate";
LastName = "Middleton";
};
var id = new PersonsRepository().Save(person1);
Only use constructors if some fields are mandatory since it's an effective way to make sure that those fields are specified.
I'm unsure as to whether the fields should be public or not
Fields usually means member variables and those should always be private. As for properties I would stick with get/set for database objects.
I'm also wondering how I should be dealing with the optional properties of the class. Once the fields have been populated how do I then save them to the DB?
Saving things to the database is a whole different story. I would not try to invent my own layer but to use an existing one. There are a whole set of different ORM:s out there from very simple to very feature complete.
Take a look at PetaPoco for a lightweight alternative or nHibernate for a more feature complete alternative.
Validation
One common way to make sure that mandatory fields are correctly specified and got valid values are to use a validation framework. There is one built into .net called DataAnnotations. Google it and look at some examples.
This should be checked by using business rules.
I mean if you want a very re-usable business model, business objects should be re-used elsewhere in different areas, and this may mean same class "A" could be fine in state "X" in some business, but in another situation, same class "A", will be fine in state "Y".
There's a good design pattern allowing you to implement business validators called Specification:
http://en.wikipedia.org/wiki/Specification_pattern
This can be implemented in a lot of ways, but one of most compact ones is by building rules with lambda expressions.
For example:
someAInstance => someAInstance.Name != null && someAInstance.Age > 30
Another way is using existing object validation libraries, like NHibernate Validator, which can be used standalone without NHibernate and allows you to put attributes in class' properties like [NotNull], [NotNullNotEmpty], and more complex rules, and you can either use built-in ones or you can build your own ones.
Learn more by reading this article (there you'll find a list of out-of-the-box validation rules):
http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx
Note that one of most important advantages of NH Validator is it can be used in any layer, not only data or business layer, and as you can use it without NHibernate, you've a light-weight, easy-to-use and multi-layered object validator.

How to make a Attribute aware of the Name of the Proprty it is on?

I want to implement a simple attribute that is used to map Database Columns to Properties.
So what i have so far is something that attached like so:
[DataField("ID")]
public int ID { get; set; }
[DataField("Name")]
public String Name { get; set; }
[DataField("BirD8")]
public DateTime BirthDay { get; set; }
Is there a way that I can make the attribute "aware" of the field it is on, so that for the properties where the name is the same as the ColumnName I can just apply the attribute without the name parameter, or would I have to deal with that at the point where I reflect the properties. I want to end up doing just this:
[DataField]
public int ID { get; set; }
[DataField]
public String Name { get; set; }
[DataField("BirD8")]
public DateTime BirthDay { get; set; }
The attribute itself won't be aware of what it's applied to, but the code processing the attributes is likely to be running through PropertyInfo values etc and finding the attributes associated with them. That code can then use both the property and the attribute appropriately.
To make things simpler, you might want to write a method on the attribute to allow it to merge its information with the information from the property, so you'd call:
DataFieldAttribute dfa = propertyInfo.GetCustomAttributes(...); // As normal
dfa = dfa.MergeWith(propertyInfo);
Note that for the sake of sanity this should create a new instance of the attribute, rather than changing the existing one. Alternatively, you might want a whole separate class to represent "the information about a data field":
DataFieldAttribute dfa = propertyInfo.GetCustomAttributes(...); // As normal
DataFieldInfo info = dfa.MergeWith(propertyInfo);
That way you could also construct DataFieldInfo objects without any reference to attributes, which might be a nice conceptual separation - allowing you to easily load the config from an XML file or something similar if you wanted to.
If you don't mind using postsharp you can look Here, at a previous question I have asked which was close. I ended up using the compile time validate to do what I wanted, although there are other options, like CompileTimeInitalize.
public override void CompileTimeInitialize(object element)
{
PropertyInfo info = element as PropertyInfo;
//....
}

Categories