13

I am playing around trying to get an application framework going that uses RavenDB. I have setup a business logic service, which has a 1 to 1 relationship with a session and effectively becomes the unit of work abstraction.

Part of the business logic service would be to contain all the validation. A method from the service might be something like

    public void StoreUser(User user)
    {
        //Some validation logic
        if(string.IsNullOrWhiteSpace(user.Name))
            throw new Exception("User name can not be empty");

        Session.Store(user);
    }

The issue is that because user is tracked as soon as it is stored i can bypass any validation on the store method but storing a correct value then changing it later

    public void TestUserStore()
    {
        var u1 = new User() {Name = "John"};
        var u2 = new User() { Name = "Amy" };

        Service.StoreUser(u1);
        u1.Name = null; //change is tracked and will persist on the next save changes
        Service.StoreUser(u2);
        Service.SaveChanges();

        //The following fails, as we have stored null as the name rather than "John" bypassing our validation
        Assert.IsTrue(Service.AdhocQuery<User>().Any(u => u.Name == "John"));

    }

Is there someway to get RavenDB to store only a snapshot of the item that was stored and not track further changes? Should i be cloning everything going into and out of the business logic service to prevent illegal update? or am i doing the validation in the wrong place is there a better place to put this logic?

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
Alex
  • 3,245
  • 2
  • 19
  • 17

1 Answers1

12

Put your validation logic inside a IDocumentStoreListener before every save, you can do this sort of check automatically.

I blogged more about this issue here.

George Stocker
  • 57,289
  • 29
  • 176
  • 237
Ayende Rahien
  • 22,925
  • 1
  • 36
  • 41
  • 4
    Great extension point, it deserves more publicity than it currently has on the documentation – Alex Oct 03 '12 at 19:27