Automatically creating DataContract classes from business object classes

I am currently creating a .NET C # API. I have many classes, and some of them must be passed using the REST service as JSON . For example, I might have an account object with lots of business metadata:

 public class Account { public ComplicatedClass SomeProperty { get; set; } public string SomeOtherProperty { get; set; } } 

There are many classes and many others that are nested (as shown in the ComplicatedClass type property). To avoid overlapping this business object on [DataMember] , etc. Attributes that will make this class messy, I want to make a DTO for JSON :

 public class AccountDTOForJSON { [DataMember(Name="someProperty")] public ComplicatedClassDTOForJson SomeProperty { get; set; } [DataMember(Name="someOtherProperty")] public string SomeOtherProperty { get; set; } } 

My problem is that there are no tools (which I can find) to automatically generate these DataContract classes, as well as provide code to display the properties back / forth.

I can, of course, do it all manually (in the worst case) or collapse my own creation / map tool (second worst case). But first, I would like to know if you have a tool for this kind of thing that I can use to save time.

+6
source share
4 answers

That's a good question. I'm actually going to do something similar to him in the project I'm working on.

I would suggest that there are two problems: firstly, generate DTO code from your business objects, and secondly, do a mapping between the business object and DTO.

I could not find a code generator for this purpose, spending about half an hour on Google. Perhaps I was not looking for the right things, or maybe not there (so if someone knows one, please call). The only tool that seems promising to me is NHydrate ( http://www.codeproject.com/Articles/42885/NHydrate-Code-Generator ), but I haven't actually downloaded or tested it.

The mapping tool I used in the past is AutoMapper ( https://github.com/AutoMapper/AutoMapper/wiki/Getting-started ) - it will try to figure out the relationship between your business objects and the DTO, and you can perform two-way matching.

+2
source

I have done this before:

  • Use the XSD tool to create circuits from your DTO build assembly.
  • Use svcutil to create the DataContracts from the .xsd generated in step 1.


Edit:

The above assumes your Account class is a DTO (since the only metric you specified in your example was that it contains two properties, so I assume that it is just used to pass state, not define behavior). If so, and you just want the DataContract version of the Account class, then the above should work. You must still provide the code to map the Account class to the serializable Account class (generated by svcutil).

+1
source

Here is a tool that I developed specifically for your needs. You can change and change the settings if you need.

https://github.com/lasuax/ClassToDataContract

0
source

You can change the code generation mechanism (the .tt file in my case or the T4 file) and add the DataMember to the DataMember property. To add it to the automatically generated POCO class, find <#=codeStringGenerator.Property(edmProperty)#> and add [DataMember] directly above it:

  var simpleProperties = typeMapper.GetSimpleProperties(entity); if (simpleProperties.Any()) { foreach (var edmProperty in simpleProperties) { #> [DataMember] <#=codeStringGenerator.Property(edmProperty)#> <# } } 

Some of the code above should already be in the T4 file. you may need to find it and modify it by adding [DataMember] .

In addition, you can create your DTO file in any place with the desired attributes. For example, the code below creates an interface for all objects in a folder named Interface, and also names the interface as I {EntityName} Repository.cs. You can generate DTO in the same way.

 foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection)) { var host = this.Host.ResolvePath("App.config"); var savepath = host.Replace("App.config","")+"Interface\\" + "I"+entity.Name+"Repository" +".cs"; var readpath = host.Replace("App.config","") + "Templates\\"; if (!File.Exists(savepath)) { using (StreamReader sr = new StreamReader(readpath+"RepositoryInterfaceTemplate.txt")) { String line = sr.ReadToEnd(); line = line.Replace("{RepositoryInterface}","I"+entity.Name+"Repository"); line =line.Replace("{EntityName}",entity.Name); using (StreamWriter sw = File.CreateText(savepath)) { sw.WriteLine(@line); } } } } 
0
source

All Articles