views:

60

answers:

1
+2  Q: 

DI and JSON.NET

I'm using JSON.NET to serialize and deserialize object for different purposes. I'm a big fan of DI but the code below gives me the chills. Is smells like bad code:

public class Foo : Baz
{
    private readonly IBar bar;

    public Foo()
        : this(ObjectFactory.GetInstance<IBar>())
    { }

    public Foo(IBar bar)
    {
       if (bar == null)
            throw new ArgumentNullException("bar");

       this.bar = bar;
    }

   ... rest of class ...
}

The default constructor is the thing that gives me the chills. I've added this to support the deserialization caused by JSON.NET:

string jsonString = ...;
string concreteBazType = ...;

Baz baz = (Baz)JsonConvert.DeserializeObject(jsonString, Type.GetType(concreteBazType);

Notice the class Foo inherrits from the abstract base class Baz!

My question to all you DI and JSON.NET geeks out there: how can I change to code to avoid the code-smell the default constructor gives me in class Foo?

+1  A: 

This is a common problem with all sorts of Data Transfer Objects, whether they fit into JSON.NET, WCF or other technologies. In fact, you could say that all application boundary-facing classes suffer from this problem to one degree or the other. The problem is equivalent for Windows Forms Controls and other display technologies.

In the other end of the application stack, we see the same issue with Configuration objects and potentially with some ORM types (such as Entity Framework classes).

In all cases, the best approach is to treat all such Boundary Objects as dumb types with more structure than behavior. We already know that this is the right thing to do for WCF DataContracts, ASP.NET MVC Views, Windows Forms Controls, etc. so it would be a well-known solution to the problem.

Just like we have Controllers to populate Views in a UI, we can have service operatoins, mappers and whatnot that map DTOs to Domain Objects. In other words, your best recourse would be to not attempt to serialize Foo at all.

Instead, define a FooJson class that represents the static structure of Foo and use a Mapper to translate between the two.

Mark Seemann