RavenDB – The great simplification
There is always a tension between giving users an interface that is simple to use and giving them something that is powerful.
With RavenDB, we run into a problem with the session interface. I mean, just take a look…
Look how many operations you can do here! Yes, it is powerful, but it is also very complex to talk about & explain. For that matter, look at the interface:
We have 4(!) different ways of querying (actually, we have more, but that is beside the point).
Something had to be done, but we didn’t want to lose any power. So we decided on the following method:
Basically, we grouped all the common methods into a super simple session interface. This means that when you need to use the session, you see only:
4 of those methods (Equals, GetHashCode, GetType, ToString) are from System.Object and one is from IDisposable. Users pretty much are going to not see those methods. The CRUD interface is there, as well as the starting point for querying. And that is it.
I think that it makes it very easy to get started with RavenDB. And all those operations that are important but uncommonly used are still there, they just require an explicit step to access them.
Comments
Good technique. Few people know how to design APIs these days.
I'll just leave this here and see what happens:
EditorBrowsableAttribute,
msdn.microsoft.com/.../...rbrowsableattribute.aspx
Addy: if you use that attribute you won't see the method at all. The technique outlined in the post just "hides" the methods that aren't applicable for most users by making them type "session.Advanced" before they can see all the rest of the functions.
@Matt - Actually, you can use that to specify "Advanced" properties which are only shown if you check the "Show Advanced Members" option for Intellisense. Not that I'd recommend it.
@Ayende - I'm unsure about this. I mean, I love the simplification effort. But having Advanced as an option seems not right. Seems like that's only a problem because we are using the var keyword, so we can't be specific to Intellisense.
For example, if you simply had the class implement both Interfaces, and you were being intentional in the code, you'd get something like:
IDocumentSession session = //whatever
So when I typed session <dot I'd only see those. If I wanted the advanced methods, I'd use the advanced interface.
But like I said, I'm not really sure. I'm intrigued, and kudos for working to make things simpler!
Matt:
the idea was to use the attribute to hide the Equals, GetHashCode, GetType, ToString which are irrelevant in that context.
For example,
www.clariusconsulting.net/.../58301.aspx
Very interesting idea, thanks.
Would you expect a scenario where you would like to have an advancedSession instance and want to have access to all methods?
Cory,
I agree that we could do it using different interfaces, sure.
But the var keyword exists, and widely used.
Alex,
You already can access all the methods.
Clever :)
I wonder how you can pull this off with released code out there already? Wouldn't this change break everything?
Frans,
Yes, it does breaks everything.
BUT, this isn't a problem for me right now, because the change is minor in terms of the code changes required.
I meant: for the user of RavenDB: their code using the session with all the methods now has to be refactored all of a sudden when they use a later build.
(not sure if that's a given / expected anyway)
Frans,
Yes, it is something that the user would need to do, but I think that this is an acceptable pain consider the work required and the benefits given from that.
Comment preview