Presenting CodeBetter.Canvas

UPDATE: A new version is available, read more at http://codebetter.com/blogs/karlseguin/archive/2009/05/25/revisiting-codebetter-canvas.aspx

I recently wrote a code-heavy 3-part series on validation. Half-way through, I realized that a sample application would
probably help bring together all the incoherent code snippets I was throwing around.

Historically, I’ve been pretty harsh on shitty code-samples (you can go back to when I first started blogging and probably
find some pretty harsh criticism of Adobe and MSDN). As a consequence, I’ve always tried to write above-average code samples,
Of course, more recently I’ve taken a number of high profile projects to task, namely Oxite and Kobe. As soon as I started putting
this sample together, I saw an opportunity to go beyond demo-ing a custom validation library and provide some of the guidance
I felt other projects were lacking.

Functionality-wise, all you can do is register a user. The downside of the simplification is that it doesn’t address
many (most?) of the real challenges you’re likely to face. Even I think the entire thing seems rather ivory tower. On the upside
you can use this project as a canvas for your own project, or as a launch-pad to learn about all types of exciting technologies.
Specifically, despite the extreme lightweightedness, this project makes use of Dependency Injection (via Ninject), OR Mapping
(via FluentNHibernate), Unit Testing (via XUnit), mocking (via RhinoMocks) and a couple more trendy topics.

This isn’t a perfect example, but I’m pretty happy with it. I think developers who have a genuine interest in learning
and enthusiasm for programming will gain a lot from this. I’m sorry for the total lack of documentation, but this is really a
help-yourself kinda thing.

I should point out that the way I handle the database path (I use sqlite) is horrible. I did it that way so that the application
will [hopefully] work out of the box (all you need in ASP.NET MVC installed). The hack in question is located in the Configuration class.
Also, this isn’t an opinionated MVC implementation. This isn’t really about MVC at all.

If you want help or have a suggestion/comment post a comment here. I’d love to help any way I can, or even better, learn
to from my mistakes so that I don’t do them again.

Finally, I apologize to the people who just wanted to peak at the validation framework. My demo turned into something more.
If I did a good job, you should be able to easily find all of the pieces.

You can download it here

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

13 Responses to Presenting CodeBetter.Canvas

  1. Girish Girigowda says:

    Is there any sample against a traditional Web form application?

  2. karl says:

    @Alex and @Gary:
    Once I can find the time, I’m going to put the source up somewhere of a v2.

  3. Gary Brunton says:

    Karl, thanks for sharing such an excellent post. This has really got me thinking.

    I do have a question though. Within your BaseValidatorAttribute class you save the entity reference and comment that it will come in handy when we need to do Compare validators.

    Could you possibly expand on that idea? Do you have an example of such a comparison?

    Thanks so much for your time!

  4. Alex says:

    Karl, will you keep updating this sample?

    I’m new to MVC, got your sample and now I’m up and running but i have lot’s of questions. Why not a google code project? Help us, the mere webforms mortals.

  5. karl says:

    Robert:
    Damnit, you found a good bug. Check out the FluentNhibernate Repository implementation (which mine is essentially a copy of, MINUS THE FREAKING TRANSACTIONS)

    http://code.google.com/p/fluent-nhibernate/source/browse/trunk/src/FluentNHibernate/Data/IRepository.cs

    I’m also thinking I should have scoped my IRepository to PerRequest.

  6. Robert says:

    Cool sample project :)

    One question:
    I’m pretty new to NHibernate so I was looking for ideas on how to use it with a web app, but there’s one thing I can’t figue out – where/when does NHibernate actually commit to the DB in this app? I was trying to find a call to Commit(), but I can’t find anything like that.

  7. Peter Goras says:

    Great stuff Karl! VS project is much better than lengthy code snippets. To see the examples in context makes a big difference.
    more of the same please!

  8. karl says:

    Justin:
    I hadn’t thought of validation from a batch-editing context.

    I don’t have a good reason for not simply using document.ready() over and over..I know you can have as many as you want. I can’t think of a good reason for it now, the code will still be coupled to jQuery, and it actually takes more time to write out..

  9. @karl Excellent post and great example. I’d love to see someone provide a working example of doing this same thing with an editable list of entities. We implemented a system similar to this, but one of the issues that came up was how would you edit something like a list of addresses? The ids of the fields would need indexes and then you would have to find a way to render the proper rules out in the ui. Definitely not impossible, but we never got around to developing a solution.

    Oh, and just curious, why are you using a placeholder inside of the document.ready function? You can use any number of document.ready functions and jquery will just chain them.

    Thanks again for the sample!

  10. saintedlama says:

    I would only expose the encrypted password as property but add a method to User something like SetPasswordPlain that does the password encryption and set the EncryptedPassword property. By this approach a developer is not surprised about the side effect of Save method in UserRepository. The only problem here is getting the IEncryptor instance into user instances created by NHibernate.

    For the UserRepository implementation my opinion is that an interface should only expose the functionality that is really needed. For UserRepository this is violated. IMHO…

  11. karl says:

    @Erik:
    Yes, I do need to look at it again. I didn’t say Oxite sucked though. I just said I was critical of it, and that Canvas attempted to address some of its shortcomings. I could have added an update to say that Oxite had changed significantly, but the post was about how we got here. I’d like to think we can reference Oxite without always adding an addendum.

    @Christoph:
    I initially tried to do it the “recommended” way, and used an IUserType with NHibernate but kept running into problems. Besides, I’m not convinced that password encryption is merely a persistence concern. Where are you thinking in goes? The controller or the User class? Could hash in the setter, and tell NHibernate to use the private field so it doesn’t get double-hashed. I don’t like it in the controller, but that might just be because I’m coming from a multi-UI system and I tend to push things down for greater reuse.

    As for IRepository, I think some people exclusively use explicit interfaces, which is pretty much what we are doing here (everything goes through the UserRepository interface). I actually don’t mind having a Controller or something use a non-explicit method, if it wants to use the base Repository’s Find method, so be it.

  12. Christoph Walcher says:

    Hi,

    just took a quick look at CodeBetter.Canvas and having two BIG question.
    What is the reason to put the IEncryptor in the UserRepository? I would also not expect the Save method of a repository to set the user’s password property.
    What is the reason to expose the full IRepository interface by deriving UserRepository from Repository? I mean most of these methods will not be needed by client code…

  13. Erik Porter says:

    Seriously, Karl. You really need to take a look at Oxite again. The way you’re doing validation is very similar to how Oxite does it (currently).

    If you’re going to continue to say how horrible Oxite is, first take a look at something other than the first release.

    Your sample is cool, but seriously, let it go and re-examine Oxite.

    -That Opinionated Oxite Guy
    :)