Gravity icon indicating copy to clipboard operation
Gravity copied to clipboard

Interface-based scoping of DTO fields

Open Arithmomaniac opened this issue 6 years ago • 1 comments

Right now, the only method for only returning or updating specific fields is on the class level. This requires either many partially duplicate classes, or manually constructing inheritance chains. Neither of these options support multiple inheritance, and they don't play nice with code generation (see #11 ).

I think at least having the option of using interfaces would be simpler:

  • A BaseDto subclass can implement one or more interfaces
  • In addition to the current single-parameter CRUD methods that return a whole object, the Dao CRUD members can take two generic parameters; the second is the interface to input/return, and the first remains the underlying class for the operation.
  • Only gettable members of the interface are used in query conditions (once we implement LINQ, see #12 ) and in reads / query results. Only settable ones are used for creates/updates.

If you generate partial classes, then consumers can scope the object to all of their needs by slapping on as many interfaces as they want. The interfaces would not need the attributes, so these would be easy to write too.

To take an example: suppose I want just want to read just the Name and OrderNumber properties on DemoPurchaseOrder, and update the FooBar property on the Items (leaving the attributes off of the classes for simplicity; the interfaces would not need them):

public class DemoPurchaseOrder : BaseDto, IDemoPurchaseOrder_UpdateFooBar
{
    public override string Name { get; set; }
    public int OrderNumber { get; set; }
    public string CustomerName { get; set; }
    public string CustomerEmail { get; set; }
    public IList<Item> Items { get; set; }
}

public class Item : BaseDto, IItem_UpdateFooBar
{
    public string Baz { get; set; }
    public string FooBar { get; set; }
}
 
public interface IDemoPurchaseOrder_UpdateFooBar
{
    string Name { get; }
    int OrderNumber { get; }
    IList<IItem_UpdateFooBar> Items { get; set; }
}

public class Item : BaseDto, IItem_UpdateFooBar
{
    string FooBar { set; }
}

//pseudocode

var demoOrder =  
    gravityRsapiDao.GetRelativityObject<DemoPurchaseOrder, IDemoPurchaseOrder_UpdateFooBar>
        (1047088, ObjectFieldsDepthLevel.FirstLevelOnly);
foreach (var item in demoOrder.Items)
{
    return item.FooBar = $"{demoOrder.Name}_{demoOrder.ItemNumber}";
    //item.Baz is not available to set
    //demoOrder.CustomerEmail is not available to get
}
gravityRsapiDao.Update(IDemoPurchaseOrder_UpdateFooBar>
    (demoOrder, ObjectFieldsDepthLevel.FirstLevelOnly);

Arithmomaniac avatar Dec 01 '17 15:12 Arithmomaniac