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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With