Question

iam creating an interface for a fluent ordered constructor and i have wrote this code:

public interface IMyObjectFactory: IObjectWithProperty
{
  int objectId { get; set; }
  IObjectWithProperty WithObjectId(int id);
}

public interface IObjectWithProperty
{
  IObjectWithProperty WithObjectId(int id);
  MyObject Create();
}

the second interface is need to enforce order in constructor method

the impl is this:

public class MyObjectFactory: IMyObjectFactory
{
    public int objectId { get; set; }
    private MyObjectFactory() { }
    public static IObjectWithProperty BeginCreation()
    {
        return new ObjectFactory();
    }
    public IObjectWithProperty WithObjectId(int id)
    {
        objectId = id;
        return this;
    }

    public MyObject Create()
    {
        return new MyObject(this);
    }
}

And this is my object:

public class MyObject
{
  public int Id { get; set; }
  public MyObject(IMyObjectFactory factory)
  {
    this.Id = factory.objectId;
  }
}

so I can write

MyObject mo = MyObjectFactory.BeginCreation().WithObjectId(1).Create();

but:

  • I have to define property both in interface and impl of the constructor and don't like much
  • the static BeginCreation method has no interface
  • I have to set public the impl property while i want it internal
  • in the interface i get this warning: Warning 7 'FunzIA.DL.Factory.Interfaces.IMyObjectFactory.WithObjectId(int)' hides inherited member 'FunzIA.DL.Factory.Interfaces.IObjectWithProperty.WithObjectId(int)'. Use the new keyword if hiding was intended.

but is not a new method and i need the second interface to enforce order

Any suggestion? Thanks

Was it helpful?

Solution 2

I do it in this way:

  • simply don't want to let class constructor to be visible, i want only the factory to be accessible


public interface IMyObjectFactory: IObjectWithProperty
{
  int objectId { get; set; }
}

public interface IObjectWithProperty
{
  IObjectWithProperty WithObjectId(int id);
  MyObject Create();
}

public class MyObjectFactory: IMyObjectFactory
{
  public int objectId;
  private MyObjectFactory() { }

  public static IObjectWithProperty BeginCreation()
  {
    return new MyObjectFactory();
  }

  public IObjectWithProperty WithObjectId(int id)
  {
    objectId = id;
    return this;
  }

  public MyObject Create()
  {
    return new MyObject(this);
  }
}

public class MyObject
{
  public int Id { get; set; }
  public MyObject(IMyObjectFactory factory)
  {
    this.Id = factory.objectId;
  }
}

OTHER TIPS

public class MyObjectFactory: IMyObjectFactory
{
  private int objectId;
  private MyObjectFactory() { }

  public static IObjectWithProperty BeginCreation()
  {
    return new ObjectFactory();
  }

  public IObjectWithProperty WithObjectId(int id)
  {
    objectId = id;
    return this;
  }

  public MyObject Create()
  {
    return new MyObject(objectId);
  }
}

public class MyObject
{
  public int Id { get; set; }
  public MyObject(int objectId)
  {
    this.Id = objectId;
  }
}

My opinion:

  • You can remove WithObjectId in IMyObjectFactory. You get it through inheritance. This setup is the reason for the warnings you get.
  • BeginCreation is fine where it is. At some point you have to create real world objects and that is not possible just with interfaces. You need real classes.
  • I would never let MyObject know about any factories. Factories know and create objects, not the other way around. Create should construct MyObject. This also results in not having the need to have the objectId property (which you do not like anyway).
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top