Removing default constructor used by YamlDotNet

1k views Asked by At

I have an object graph containing nodes of various types. All nodes derive from a Node class. Using YamlDotNet I've managed to serialize and deserialize the graph by providing my own implementation of IObjectFactory. The only thing left to do is to get rid of a constructor that only exists to please the YamlDotNet serializer.

Have a look at the following .NET fiddle https://dotnetfiddle.net/KJMzxD

The FancyNode.ctor() is the constructor I would like to remove but I'm not sure how to tell the serializer that I've handled everything in the deserializer. If I simply remove it I get the following error

Type 'FancyNode' cannot be deserialized because it does not have a default constructor or a type converter.

1

There are 1 answers

1
404 On

If you only want to get rid of the parameterless constructor code rather than the constructor itself - given it's required for that type of deserialisation - you could remove both constructors and use a factory method to create the nodes. That would result in the class having a default public constructor.

For example, change:

public class FancyNode : Node
{
  private IController controller;

  public string ID
  {
      get;
      private set;
  }

  // I would really like to get rid of this constructor
  public FancyNode()
  {
      throw new NotSupportedException();
  }

  // NOTICE: no default constructor here  
  public FancyNode(IController controller, string id)
  {
      this.controller = controller;
      this.ID = id;
  }
}

to:

public class FancyNode : Node
{
    private IController controller;

    public string ID
    {
        get;
        private set;
    }

    public static FancyNode CreateNode(IController controller, string id)
    {
        var node = new FancyNode();
        node.controller = controller;
        node.ID = id;
        return node;
    }
}

Yes you lose the tight control you have that doesn't allow the object to be created without passing those parameters in, given that anyone can now do var x = new FancyNode(). Then again you aren't validating the parameters so it makes no difference to calling it with new FancyNode(null, null).