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?
The Newtonsoft. JSON namespace provides classes that are used to implement the core services of the framework. It provides methods for converting between . NET types and JSON types.
Json uses reflection to get constructor parameters and then tries to find closest match by name of these constructor parameters to object's properties. It also checks type of property and parameters to match. If there is no match found, then default value will be passed to this parameterized constructor.
Serialization is the process of converting . NET objects such as strings into a JSON format and deserialization is the process of converting JSON data into . NET objects.
Json.NET is open source software and is completely free for commercial use.
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 operations, 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With