Auto generating DataContract classes from Business Object Classes
Asked Answered
G

5

7

I'm currently creating a .NET C# API. I have many classes, and some of them have to be transferred through a REST service as JSON. For example, I may have an account object with a lot of business meta-data:

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

There are many classes, and many more that are nested (as demonstrated by ComplicatedClass type property). To avoid inundating this business-object with [DataMember] etc. Attributes that will make this class a mess, 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, there doesn't seem to be any tools (that I can find) to auto-generate these DataContract classes, and also provide code for mapping properties back/forth.

I can, of course, do all this work manually (worst case), or roll my own tool to generate/map (second worse case). But, I'd like to know first if there's already a tool to do this kind of thing that I can use to save myself time.

Goodyear answered 1/2, 2013 at 18:12 Comment(0)
M
2

This is a good question. I'm actually going to be doing something similar to it in a project I am working on.

I would suggest that there are really two problems here: the first is to generate DTO code from your business objects, and the second is to do the mapping between business object and DTO.

I could not find a code generator for this purpose after spending about a half hour on Google. Perhaps I'm not searching for the right thing, or possibly there isn't one out there (so if someone knows of one, please chime in). The only tool I found that looks promising is NHydrate (http://www.codeproject.com/Articles/42885/NHydrate-Code-Generator), but I did not actually download it or test it.

A mapping tool that I've used in the past is AutoMapper (https://github.com/AutoMapper/AutoMapper/wiki/Getting-started) - it will attempt to figure out the relationship between your business objects and DTOs, and will be able to do two-way mapping.

Musjid answered 1/2, 2013 at 19:19 Comment(2)
Thanks! I'm glad I'm not the only one who ran into this.. I too cannot find anything. I did find the AutoMapper you talked about, but I feel like if I have to roll the generator, I might as well roll my own mapper too.. It's very odd nobody has run into this yet..Goodyear
yes it would be cool with a tool like the online json parser json.parser.online.fr if it could show C# datacontract code also - I used the online json parser to help me with the manual task of creating the DataMembers - tedious job and it should be possible to make a simple parserStegodon
O
1

I've done this before by:

  1. Use the XSD tool to generate schemas from your compiled DTO assembly.
  2. Use svcutil to generate DataContracts from the .xsd generated in step 1.


Edit:

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

Owsley answered 1/2, 2013 at 18:45 Comment(1)
I think you miss-understood - I don't have any DTO files generated yet.. that's what I want to generate. All I have is the Business Objects.Goodyear
N
1

On way is to modify your code generation engine (.tt file in my case or the T4 file) and add the DataMember attribute to the properties you want. To add it to an auto generated POCO class, look for the <#=codeStringGenerator.Property(edmProperty)#> and add the [DataMember] right above it:

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

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

Also, you can create your DTO file in an arbitrary location with desired attributes. For example the code below is creating an interface for all the entities in a folder named Interface and also name the interface like I{EntityName}Repository.cs. You can generate DTOs 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);        
        }
      }
    }
}
Neill answered 6/2, 2019 at 20:15 Comment(0)
G
0

Here is a tool that I've developed exactly for your needs. You can fork and change settings if you need to.

https://github.com/lasuax/ClassToDataContract

Garlaand answered 9/3, 2017 at 21:13 Comment(0)
P
0

EggBlox has done a pluging that one of its fonction is exactly to implement DataContract http://www.eggblox.com/ It requires JetBrain Reshaper

Pansy answered 28/9, 2020 at 17:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.