<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-687621843647502226</id><updated>2011-07-08T05:21:29.363-07:00</updated><category term='C#'/><category term='SRP'/><category term='Patterns'/><category term='MVC'/><category term='Linq'/><title type='text'>C#</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codechunk.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/687621843647502226/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://codechunk.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Yngve B. Nilsen</name><uri>http://www.blogger.com/profile/02774764185708808952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-687621843647502226.post-8878991991278781772</id><published>2009-09-29T00:25:00.000-07:00</published><updated>2009-09-29T00:38:33.051-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SRP'/><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><title type='text'>Building a site – What am I doing wrong? (3)</title><content type='html'>&lt;h1&gt;Part 3 - Slimming down my classes&lt;/h1&gt;&lt;div&gt;&lt;a href="http://codechunk.blogspot.com/2009/09/building-site-what-am-i-doing-wrong.html"&gt;Part 1 and 2 here&lt;/a&gt;&lt;/div&gt;&lt;div&gt;So I did a brief overview of my structure in the previous post, and you might remember to significant classes/interfaces - IEntity and DacBase.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I told you I'd throw patterns out the window and see where it led me... Well, to be honest, it leads me back to, yes you guessed it, patterns! :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my previous article, I had put CRUD-methods directly on my data-models like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_mf5vLXYcJAA/SsG3MuncjzI/AAAAAAAAAGE/EuE3AaNYljQ/s1600-h/Old+User.PNG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 305px;" src="http://2.bp.blogspot.com/_mf5vLXYcJAA/SsG3MuncjzI/AAAAAAAAAGE/EuE3AaNYljQ/s320/Old+User.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5386788058611617586" /&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To be honest with you (and you probably already see the problem) - This would be a major hassle everytime I need a new model, because I have to implement all the CRUD and relation work everytime. The beauty of it is that all the CRUD-methods are totally generic, and don't give a crap about what object they are hosted in, as long as they have something to do with IEntity.&lt;/div&gt;&lt;div&gt;So I thought, let's move them out from the models and into the DacBase, that all my models needs to inherit from.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what I end up with is.... *drumroll*&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_mf5vLXYcJAA/SsG4BBdr9MI/AAAAAAAAAGM/avymbnB-S3U/s1600-h/New+user.PNG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 207px;" src="http://3.bp.blogspot.com/_mf5vLXYcJAA/SsG4BBdr9MI/AAAAAAAAAGM/avymbnB-S3U/s320/New+user.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5386788957024154818" /&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you can see, I have no methods conserning CRUD (Well, actually the User-model still has some data-fetching in the last constructor, but that'll go away too). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ultimately I'd like for my model to only have one empty constructor that calls the base-constructor, and of course my fields.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But this is actually pulling me towards the Single Responsibility Pattern - And that's just because it felt more practical and easy for me. Not because I decided to follow that pattern at all. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I just want to add that all my integration-tests ran perfectly after I changed my code (and the reason for my tests is not that I want to do TDD, but simply because it's so much easier than to pull up a browser in debug-mode and click all around my site :))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Conclusion Part 3&lt;/b&gt;&lt;/div&gt;&lt;div&gt;As you can see, I've already started following one of the many patterns out there, so let's see how many patterns I end up following simply by ignoring them :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Stay tuned.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh! And after posting my &lt;a href="http://codechunk.blogspot.com/2009/09/building-site-what-am-i-doing-wrong.html"&gt;previous post&lt;/a&gt; got hit by a series of spambots auto-kicking it and ultimately getting me banned from DNK :( Working on getting that fixed.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/687621843647502226-8878991991278781772?l=codechunk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codechunk.blogspot.com/feeds/8878991991278781772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=687621843647502226&amp;postID=8878991991278781772' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/687621843647502226/posts/default/8878991991278781772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/687621843647502226/posts/default/8878991991278781772'/><link rel='alternate' type='text/html' href='http://codechunk.blogspot.com/2009/09/building-site-what-am-i-doing-wrong-3.html' title='Building a site – What am I doing wrong? (3)'/><author><name>Yngve B. Nilsen</name><uri>http://www.blogger.com/profile/02774764185708808952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_mf5vLXYcJAA/SsG3MuncjzI/AAAAAAAAAGE/EuE3AaNYljQ/s72-c/Old+User.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-687621843647502226.post-893380490827918935</id><published>2009-09-25T10:09:00.000-07:00</published><updated>2009-09-25T11:22:17.227-07:00</updated><title type='text'>Building a site – What am I doing wrong?</title><content type='html'>&lt;h1&gt;Part 1 - Introduction&lt;/h1&gt;&lt;h2&gt;Disclaimer – sort of...&lt;/h2&gt;&lt;p&gt;The stuff I’ll be showing in this series of posts is not necessarily wrong , but it might be “wrong” according to some of the patterns and practices that have emerged over the last couple of years. Acronyms like KISS, DRY, SOLID, YAGNI and so on are on every blogs lips, and I kind of decided to throw them out of the window, and just doing what I thought was logical at the time of programming, and according to my needs and the functionality in the application.&lt;br /&gt;Of course, I’ve read loads of articles, and my programming structure has definitely been influenced by all of them, so it’s not that I’m avoiding the principles, but simply not thinking about them as I write out my application.&lt;/p&gt;&lt;h2&gt;The Project&lt;/h2&gt;&lt;p&gt;I’ve decided to build a site for sharing pictures among friends (yeah, yeah – it’s already out there, but who cares). I’ll start out pretty simple and see where it ends.&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;The initial functionality includes&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Logging in/Registering&lt;/li&gt; &lt;li&gt;Creating groups that you and your friends can share and upload pictures to&lt;/li&gt; &lt;li&gt;Uploading pictures&lt;/li&gt; &lt;li&gt;Commenting on groups or pictures&lt;/li&gt; &lt;li&gt;Giving other users access to your group&lt;/li&gt;&lt;/ul&gt;Should be fairly simple to put together, but that’s not really the point here. Read on :)&lt;br /&gt;&lt;h2&gt;The Point&lt;/h2&gt;&lt;p&gt;I want to do a bit of overkill in this application, and imagining that it will be scaled out, extended with more functionality, changing the datasource etc, etc. Hence, a lot of the code I’ll be showing will be overkill. I know this.&lt;br /&gt;What would be great would be to get some feedback/thoughts/ideas about what I’m doing right/wrong and why it’s so wrong.  I’m also doing this just to try stuff out, and see if I can figure out new and smart ways to resolve problems and implement functionality.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The Technical specs&lt;/h2&gt;I’ll be using the following applications and technologies when developing&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Visual Studio 2008&lt;/li&gt;&lt;li&gt;Microsoft SQL Server 2008&lt;/li&gt;&lt;li&gt;C# .NET 3.5&lt;/li&gt;&lt;li&gt;MVC&lt;/li&gt;&lt;li&gt;Linq To SQL&lt;/li&gt;&lt;li&gt;JQuery&lt;/li&gt;&lt;/ul&gt;&lt;h1&gt;Part 1 – The Database&lt;/h1&gt;&lt;p&gt;I’m gonna start off by showing of the databasestructure and explaining a few of my choices.&lt;br /&gt;First of all – a screenshot&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_mf5vLXYcJAA/Srz9Nh4SEFI/AAAAAAAAAE0/KFm3y7JC7Qk/s1600-h/db.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_mf5vLXYcJAA/Srz9Nh4SEFI/AAAAAAAAAE0/KFm3y7JC7Qk/s320/db.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5385457663302832210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The Tables&lt;/h2&gt;&lt;br /&gt;I’ve gone for a many-to-many relational model, and I’m using Unique Identifiers (GUIDS) as the primary keys in the database. More on this later, when we look at some code.&lt;br /&gt;&lt;h3&gt;User&lt;/h3&gt;&lt;br /&gt;I decided to include only the stuff I need for logging in here, so Email and Password is all I need&lt;br /&gt;&lt;h3&gt;UserProfile&lt;/h3&gt;&lt;br /&gt;I’ll probably expand this table as we go on, but it will basically be an extension of the User-table, keeping all sorts of profile-information for each user&lt;br /&gt;&lt;h3&gt;Group&lt;/h3&gt;&lt;br /&gt;The group will be what is containing the pictures, but the definition is so far limited to a name&lt;br /&gt;&lt;h3&gt;Comment&lt;/h3&gt;&lt;br /&gt;Simply a table containing the comments for whatever is commented on&lt;br /&gt;&lt;h3&gt;Image&lt;/h3&gt;&lt;br /&gt;The actual information about the uploaded image&lt;br /&gt;&lt;h3&gt;TimeStamp&lt;/h3&gt;&lt;br /&gt;This will be available to all tables, since I’m probably gonna need timestamps for all kinds of entities.&lt;br /&gt;&lt;h3&gt;Relation&lt;/h3&gt;&lt;br /&gt;This is the reason for the Unique identifiers.&lt;br /&gt;This table will keep all the relations between any entities. As you will see later, I’m managing the relations through code, so no relations in the database&lt;br /&gt;Yes, I know, many of you will probably scream in agony right now, but that’s what I want. I would like you to tell me why I definitely shouldn’t choose this approach.&lt;br /&gt; &lt;br /&gt;&lt;h1&gt;Part 2 – The DataAccess layer&lt;/h1&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;LinqToSql&lt;/h2&gt;&lt;br /&gt;Even though I love the ease of using Linq to chat with my Db, I don’t like having my application tightly coupled to the database, so I’ve decided to have my own Entities defined, and mapping to them through repositories.&lt;br /&gt;By doing this I should have the opportunity to change my datasource some time in the future. I should also be able to switch to some other ORM like NHibernate or similar.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The Repository&lt;/h2&gt;&lt;br /&gt;I’m going for a pretty tedious model here and decided to go with a structure that Rob Conery used in his early videos in the MVC Storefront video-series. The main difference is that I’ve declared a generic Repository Interface that all my repositories will implement.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_mf5vLXYcJAA/Sr0ArGZZkOI/AAAAAAAAAE8/5SvV8v44lzc/s1600-h/IRepository.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 105px;" src="http://1.bp.blogspot.com/_mf5vLXYcJAA/Sr0ArGZZkOI/AAAAAAAAAE8/5SvV8v44lzc/s320/IRepository.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5385461469856501986" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I will show you the IEntity interface shortly, but first a few notes about this interface.&lt;br /&gt;This is what I need for CRUD (Create, Read, Update and Delete)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Save-method will either create a new object in the database, or update an existing one&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The Get-method returns an IQueryable of my mapped class, so no actual querying is done until the recordset is accessed.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The Delete-method will simply delete the object from the database&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The &lt;t&gt; is my mapped class.&lt;br /&gt;I’ll get back to implementation later on.&lt;br /&gt;&lt;h2&gt;The IEntity&lt;/h2&gt;&lt;br /&gt;I’ve decided that all of my internal mapped objects need to implement the interface IEntity. Hopefully, you’ll understand the reason for this approach when you see the implementation. But this is where the patterns starts falling out :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_mf5vLXYcJAA/Sr0Bpu4vi_I/AAAAAAAAAFE/XhF5ZMS4zgA/s1600-h/IEntity.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 105px;" src="http://1.bp.blogspot.com/_mf5vLXYcJAA/Sr0Bpu4vi_I/AAAAAAAAAFE/XhF5ZMS4zgA/s320/IEntity.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5385462545877273586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see, I’m putting logic in my class, totally ignoring the S in SOLID (Single responsibility). But as you’ll see, I find that this provides me with a very fluent way of programming. I have a couple of ideas to sort this out, but I’ll talk more about that when we get to implementations. I’ve also included constraints on my generics.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;All my objects have an Id, so I put that in the IEntity in order to manage relations in a generic matter&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Save, will actually call the save-method in the repositories (I’m definitely in need of some advice here, so keep reading)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Delete does the same as Save, but deletes the object&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Remove&lt;t&gt; will remove a relation to another object&lt;/t&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Add&lt;t&gt; will add a relation to another object&lt;/t&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;DacBase&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Finally I wrote an abstract class DacBase&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_mf5vLXYcJAA/Sr0ByxPMrkI/AAAAAAAAAFM/X3A2ydA4IHM/s1600-h/DacBase.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 251px; height: 320px;" src="http://3.bp.blogspot.com/_mf5vLXYcJAA/Sr0ByxPMrkI/AAAAAAAAAFM/X3A2ydA4IHM/s320/DacBase.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5385462701127151170" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The reason for this class is simply to hold fields and properties that are common to all objects of type  IEntity. As you see, this is where I use my TimeStamps from the database (I minimized the Save()-method due to space. All it really does is save the information to the database)&lt;br /&gt;The IRepository&lt;t&gt; gets a repository from the Static class Repository which I will show in a second. I also use the constructor in the DacBase to create a new Guid, so I won’t have to do that in all of my actual data-classes.&lt;br /&gt;What’s important in this class is the Relations protected field. This acts as the binder between my related objects.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_mf5vLXYcJAA/Sr0B9wqFysI/AAAAAAAAAFU/ODfDY147w5w/s1600-h/Relation1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 190px; height: 320px;" src="http://4.bp.blogspot.com/_mf5vLXYcJAA/Sr0B9wqFysI/AAAAAAAAAFU/ODfDY147w5w/s320/Relation1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5385462889950071490" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/t&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;As you can see, this is completely generic, not having to think about what kind of object we’re relating. This is because the Guid Id is in the IEntity interface, and the IRepository accepts IEntity as T. This all really adds up nicely in the implementation of the objects.&lt;br /&gt;The Relation-class is also important in this setting:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_mf5vLXYcJAA/Sr0CXmwwNiI/AAAAAAAAAFc/gHmyZl5jkas/s1600-h/Relation1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 190px; height: 320px;" src="http://2.bp.blogspot.com/_mf5vLXYcJAA/Sr0CXmwwNiI/AAAAAAAAAFc/gHmyZl5jkas/s320/Relation1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5385463333970261538" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Ufortunatly, in this version of the code I’m cheating, and accessing the Linq Datacontext directly, but I’ll fix that. I’ve also implemented the IEnumerable interface, to get list-functionality on the object. You’ll see why a little later.&lt;br /&gt;Repository static class&lt;br /&gt;Now this is a dirty class - yes I know. So please suggest ways to improve this!&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_mf5vLXYcJAA/Sr0Cg9CZN4I/AAAAAAAAAFk/A4EDeza9QvM/s1600-h/Repository.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 85px;" src="http://4.bp.blogspot.com/_mf5vLXYcJAA/Sr0Cg9CZN4I/AAAAAAAAAFk/A4EDeza9QvM/s320/Repository.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5385463494568654722" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;But it basically returns the correct repository based on the type of the class asking for it.&lt;br /&gt; &lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Implementation&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;So let’s take a look at an implementation of one of my dataclasses. I Chose the User-class as an example.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_mf5vLXYcJAA/Sr0CohJuLnI/AAAAAAAAAFs/HmYkDC7mEYk/s1600-h/User.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 205px; height: 320px;" src="http://4.bp.blogspot.com/_mf5vLXYcJAA/Sr0CohJuLnI/AAAAAAAAAFs/HmYkDC7mEYk/s320/User.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5385463624522149490" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;As you might see, I’m totally disregarding SRP (Single Responsibility) here, and adding both Save, delete and so on in the dataclass.&lt;br /&gt;Now you’ve seen the basics of my setup, and I’d like your feedback.&lt;br /&gt;Just to show you an example of code to access for instance a comment and its related items:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_mf5vLXYcJAA/Sr0C5bCYzHI/AAAAAAAAAF8/qa7qN7IDyu8/s1600-h/example.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 119px;" src="http://1.bp.blogspot.com/_mf5vLXYcJAA/Sr0C5bCYzHI/AAAAAAAAAF8/qa7qN7IDyu8/s320/example.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5385463914938551410" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;What’s happening:&lt;/h3&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Gets the user with email (username) me@test.com&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Gets all the groups related to the user&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Gets the first group&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Gets the comments for the group&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Gets the first comment&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Gets the author of the comment&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Adds a new comment to the first image in the group&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;It might be just me, but I think that’s a pretty easy way to work with my data.&lt;br /&gt;&lt;br /&gt;Stay tunes. I’ll be continuing writing out this series. In the next part I’ll probably go a little more into how I use this when I start building the MVC-part of the application.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/t&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/687621843647502226-893380490827918935?l=codechunk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codechunk.blogspot.com/feeds/893380490827918935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=687621843647502226&amp;postID=893380490827918935' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/687621843647502226/posts/default/893380490827918935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/687621843647502226/posts/default/893380490827918935'/><link rel='alternate' type='text/html' href='http://codechunk.blogspot.com/2009/09/building-site-what-am-i-doing-wrong.html' title='Building a site – What am I doing wrong?'/><author><name>Yngve B. Nilsen</name><uri>http://www.blogger.com/profile/02774764185708808952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_mf5vLXYcJAA/Srz9Nh4SEFI/AAAAAAAAAE0/KFm3y7JC7Qk/s72-c/db.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-687621843647502226.post-4415631739060459156</id><published>2009-02-24T05:44:00.001-08:00</published><updated>2009-02-24T09:36:47.149-08:00</updated><title type='text'>Fun with extension-methods</title><content type='html'>I noticed the blog &lt;a href="http://www.dotnetkicks.com/csharp/Ruby_inspired_C_Extension_Methods_for_natural_DateTime_operations"&gt;Ruby inspired C# Extension Methods for natural DateTime operations&lt;/a&gt; on &lt;a href="www.DotNetKicks.com"&gt;DotNetKicks&lt;/a&gt; earlier today, and felt like trying to write this on my own, and also extend it to show off a couple of other posibilities by using extension-methods in .NET 3.5.&lt;br /&gt;&lt;p&gt; Before I go on, I'd like to give credit to the original poster, and point out that it was spavkov that initially submitted the story. I just wanted to extend it a bit, and show off some code :)&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The Extension-methods&lt;/h2&gt;&lt;br /&gt;An extension method is simply a method put in a static class, and it's purpose is to extend the functionality of some existing class, much like the ToString() or ToInt32() methods that we use all the time. In .NET 3.5 we get the opportunity to extend our own classes, as well as the existing classes of the framework with our own extension-methods. Sweet! :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;An example of some extension method could be&lt;/p&gt;&lt;br /&gt;&lt;span class="codeBlock"&gt;&lt;br /&gt;&lt;span class="keyword"&gt;public static string&lt;/span&gt; Foo(&lt;span class="keyword"&gt;this string&lt;/span&gt; s)&lt;br /&gt;{&lt;br /&gt;    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt; s + &lt;span class="string"&gt;"Bar"&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;    Notice the &lt;span class="codeBlock"&gt;&lt;span class="keyword"&gt;this string&lt;/span&gt; s&lt;/span&gt; parameter, as this is key in extension-methods. It points back to the caller of the method.&lt;br /&gt;&lt;br /&gt;    In the mentioned example we could go something like:&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;    &lt;span class="codeBlock"&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;string&lt;/span&gt; s = "Foo";&lt;br /&gt;&lt;br /&gt;    s = s.Foo();&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;br /&gt;    and our string s would now read &amp;quot;FooBar&amp;quot;;&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;    Simple as that. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Readability&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;One of the main advantages I like with extensionmethods is what it does to readability, and ease of code-mainenance. So in the next example I'll show quickly how to implement extensions for DateTime and Booleans to make some weird but fun extension-methods.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Making the 1.Days() method&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;To create this extension-method we need to initially identify what type we are extending. 1 is an integer, so it feels right to make an extension-method that extends int.&lt;br /&gt;&lt;br /&gt;Here we go:&lt;br /&gt;&lt;br /&gt;&lt;span class="codeBlock"&gt;&lt;br /&gt;&lt;span class="keyword"&gt;public static &lt;/span&gt;&lt;span class="typeName"&gt;TimeSpan &lt;/span&gt; Days(&lt;span class="keyword"&gt;this int&lt;/span&gt; i)&lt;br /&gt;{&lt;br /&gt;    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="typeName"&gt;TimeSpan&lt;/span&gt;.FromDays(i);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Complicated? Nope! And now I can write &lt;br /&gt;&lt;br /&gt;&lt;span class="codeBlock"&gt;&lt;br /&gt;&lt;span class="typeName"&gt;DateTime&lt;/span&gt; twoDaysAhead = &lt;span class="typeName"&gt;DateTime&lt;/span&gt;.Now + 2.Days();&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Now, I wont copy the original post, so I'll go right ahead with my own crazy idea. Extending Boolean.&lt;br /&gt;&lt;h3&gt;&lt;span class="keyword"&gt;true&lt;/span&gt;.If?&lt;/h3&gt;&lt;br /&gt;If anyone ends up reading this post, I will most definitely be flamed for the following example, but I think it's pretty fun and gives a nice &lt;br /&gt;example on how you can use extensions to link several expressions together to form readable code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let start by implementing the If() extensionmethod:&lt;br /&gt;&lt;br /&gt;&lt;span class="codeBlock"&gt;&lt;br /&gt;&lt;span class="keyword"&gt;public static&lt;/span&gt;&lt;span class="typeName"&gt; Boolean&lt;/span&gt; If(&lt;span class="keyword"&gt;this&lt;/span&gt;&lt;span class="typeName"&gt; Boolean&lt;/span&gt; b, &lt;span class="typeName"&gt; Boolean&lt;/span&gt; expression)&lt;br /&gt;{&lt;br /&gt;    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt; (expression) &lt;br /&gt;        &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt; b;&lt;br /&gt;    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;else &lt;/span&gt;&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;return &lt;/span&gt;!b;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;What this does, is refer back to the caller (this Boolean b), and also take some Boolean expression, returning back b if the expression evaluates to true. Otherwise switch b around, and return that.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Why?&lt;br /&gt;&lt;br /&gt;Because now I can write something like:&lt;br /&gt;&lt;br /&gt;&lt;span class="codeBlock"&gt;&lt;br /&gt;&lt;span class="typeName"&gt;Boolean&lt;/span&gt; myFooBarTest = &lt;span class="keyword"&gt;true&lt;/span&gt;.If(&lt;span class="string"&gt;"Foo"&lt;/span&gt; == &lt;span class="string"&gt;"Bar"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, we could write for instance:&lt;br /&gt;&lt;br /&gt;&lt;span class="codeBlock"&gt;&lt;br /&gt;&lt;span class="typeName"&gt;Boolean&lt;/span&gt; myFooBarTest = &lt;span class="keyword"&gt;true&lt;/span&gt;.If(((&lt;span class="string"&gt;"Foo"&lt;/span&gt; == &lt;span class="string"&gt;"Bar"&lt;/span&gt;) &amp;&amp; (&lt;span class="string"&gt;"Foo"&lt;/span&gt; != &lt;span class="string"&gt;"Foo"&lt;/span&gt;)) || (&lt;span class="string"&gt;"Bar"&lt;/span&gt; == &lt;span class="string"&gt;"Bar"&lt;/span&gt;));&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;but again, I'd like to introduce two more extensions in order to make this line even more readable:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="codeBlock"&gt;&lt;br /&gt;&lt;span class="keyword"&gt;public static&lt;/span&gt;&lt;span class="typeName"&gt; Boolean&lt;/span&gt; And(&lt;span class="keyword"&gt;this&lt;/span&gt;&lt;span class="typeName"&gt; Boolean&lt;/span&gt; b, &lt;span class="typeName"&gt; Boolean&lt;/span&gt; expression)&lt;br /&gt;{&lt;br /&gt;    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt; b &amp;&amp; expression;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;public static&lt;/span&gt;&lt;span class="typeName"&gt; Boolean&lt;/span&gt; Or(&lt;span class="keyword"&gt;this&lt;/span&gt;&lt;span class="typeName"&gt; Boolean&lt;/span&gt; b, &lt;span class="typeName"&gt; Boolean&lt;/span&gt; expression)&lt;br /&gt;{&lt;br /&gt;    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;  b || expression;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This enables me to rewrite the above line to:&lt;br /&gt;&lt;br /&gt;&lt;span class="codeBlock"&gt;&lt;br /&gt;&lt;span class="typeName"&gt;Boolean&lt;/span&gt; myFooBarTest = &lt;span class="keyword"&gt;true&lt;/span&gt;.If(&lt;span class="string"&gt;"Foo"&lt;/span&gt; == &lt;span class="string"&gt;"Bar"&lt;/span&gt;).And(&lt;span class="string"&gt;"Foo"&lt;/span&gt; != &lt;span class="string"&gt;"Foo"&lt;/span&gt;).Or(&lt;span class="string"&gt;"Bar"&lt;/span&gt; == &lt;span class="string"&gt;"Bar"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;h3&gt;The end&lt;/h3&gt;&lt;br /&gt;And that's basically what I wanted to show you. Linking several expressions by using extension methods.&lt;br /&gt;&lt;br /&gt;Thanks for reading!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/687621843647502226-4415631739060459156?l=codechunk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codechunk.blogspot.com/feeds/4415631739060459156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=687621843647502226&amp;postID=4415631739060459156' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/687621843647502226/posts/default/4415631739060459156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/687621843647502226/posts/default/4415631739060459156'/><link rel='alternate' type='text/html' href='http://codechunk.blogspot.com/2009/02/i-noticed-blog-ruby-inspired-c.html' title='Fun with extension-methods'/><author><name>Yngve B. Nilsen</name><uri>http://www.blogger.com/profile/02774764185708808952</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry></feed>
