Karl Seguin

Sponsors

The Lounge

Advertisement

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


Posted Tue, Apr 28 2009 10:25 PM by karl

[Advertisement]

Comments

Karl Seguin wrote Validation - Part 3 - Server-Side
on Tue, Apr 28 2009 10:43 PM

Validation - Part 3 - Server-Side <Update> You can download the sample application from here .

Erik Porter wrote re: Presenting CodeBetter.Canvas
on Wed, Apr 29 2009 1:21 AM

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

:)

DotNetShoutout wrote Presenting CodeBetter.Canvas - Karl Seguin - CodeBetter.Com - Stuff you need to Code Better!
on Wed, Apr 29 2009 2:59 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

Christoph Walcher wrote re: Presenting CodeBetter.Canvas
on Wed, Apr 29 2009 3:19 AM

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...

karl wrote re: Presenting CodeBetter.Canvas
on Wed, Apr 29 2009 7:32 AM

@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.

saintedlama wrote re: Presenting CodeBetter.Canvas
on Wed, Apr 29 2009 9:52 AM

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...

Justin Etheredge wrote re: Presenting CodeBetter.Canvas
on Wed, Apr 29 2009 3:20 PM

@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!

karl wrote re: Presenting CodeBetter.Canvas
on Wed, Apr 29 2009 4:34 PM

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..

9eFish wrote Presenting CodeBetter.Canvas - Karl Seguin - CodeBetter.Com - Stuff you need to Code Better!
on Wed, Apr 29 2009 9:43 PM

9efish.感谢你的文章 - Trackback from 9eFish

Peter Goras wrote re: Presenting CodeBetter.Canvas
on Thu, Apr 30 2009 8:08 AM

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!

Robert wrote re: Presenting CodeBetter.Canvas
on Fri, May 1 2009 3:48 PM

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.

karl wrote re: Presenting CodeBetter.Canvas
on Fri, May 1 2009 5:09 PM

Robert:

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

code.google.com/.../IRepository.cs

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

Karl Seguin wrote Part of your job should be to learn
on Thu, May 7 2009 8:34 AM

Jan recently asked: "Something I don't see being addressed that often - When you say you read

Alex wrote re: Presenting CodeBetter.Canvas
on Mon, May 18 2009 4:14 PM

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.

Gary Brunton wrote re: Presenting CodeBetter.Canvas
on Fri, May 22 2009 6:59 PM

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!

karl wrote re: Presenting CodeBetter.Canvas
on Fri, May 22 2009 8:33 PM

@Alex and @Gary:

Once I can find the time, I'm going to put the source up somewhere of a v2.

Karl Seguin wrote Revisiting CodeBetter.Canvas
on Mon, May 25 2009 9:12 AM

A month ago I released CodeBetter.Canvas , a simple application with equally simple goals: Provide developers