1

I am working with an abstract class RepositoryItemBase as follows:

public abstract class RepositoryItemBase : ICloneable, IEquatable<Dto>
{
    protected internal Guid Id => Guid.NewGuid();

    protected RepositoryItemBase() { }

    public object Clone()
    {
        return MemberwiseClone();
    }

    public bool Equals(Dto other)
    {
        //??
    }
}

Since the intention is to save it to a repository, I made the following design choices:

  1. When I call repo.Save(repoItem), I want the item to be cloned upon saving, so that I can keep editing it without changing the stored reference, until I call repo.Save(repoItem) again;
  2. If I call Save with an item with same Id but different property values, I want it to call the private repo.Update(repoItem);
  3. If I call Save and a stored item with same Id also has the same property values, the method returns immediately witout actually persisting anything;

My questions are:

  • Are there common C#/.Net idioms / interfaces to differentiate an Id-based comparison and a property-value-based comparison? I would like to independently perform these two types of comparison.

  • Is IEquatable the best interface to implement?

  • Does .Net have some sort of IIdentifiable or IIdentity interface, with a Guid Id { get; } property or something like that?

Community
  • 1
  • 1
heltonbiker
  • 26,657
  • 28
  • 137
  • 252
  • You are guaranteed to sooner or later shoot yourself in the foot with semantics of your point #1. #2 and #3 are hard to define (what exactly _is_ a "different property value"?) – Anton Gogolev Oct 03 '16 at 14:27
  • 1
    The way EntityFramework does it is it keeps a hidden private copy of all the original values and compare against those when it does #3. – Scott Chamberlain Oct 03 '16 at 14:27
  • @AntonGogolev thanks for your input! My RepositoryItemBase should have (by convention) subclasses where all properties are value properties, so that comparison is straightforward. – heltonbiker Oct 03 '16 at 14:32
  • @AntonGogolev regarding items 2 and 3, I believe the semantics is acceptable. If the client want to store an instance, it just passes it to the repo. The fact that the repo has a previous version of that instance would be of no interest to the client code, most of times, but if the client worries about it, it can test before saving, I guess. I would be glad if you could elaborate! :o) – heltonbiker Oct 03 '16 at 14:34
  • @ScottChamberlain do you have a link for the source code of that part? I would love to take a look! – heltonbiker Oct 03 '16 at 14:37
  • @heltonbiker not sure that it will help, but you can try to investigate this https://referencesource.microsoft.com/#System.Data.Entity/System/Data/Objects/EntityEntry.cs,4f9d7ea9165d427a,references – tym32167 Oct 03 '16 at 14:44
  • @ScottChamberlain. I think Scott is on the right track. If you're ultimately persisting using the entity framework, then you don't need the repository to do this for you, and you can still use the repository to test. Are you using the entity framework (or another ORM)? – Chad McGrath Oct 03 '16 at 14:53
  • 1
    @ChadMcGrath I am not using any framework, just plain old JSON serialization to a single file per repo. – heltonbiker Oct 03 '16 at 14:55

0 Answers0