Why There's Nothing Wrong With Dependency Injection in NerdDinner

Last week Jimmy Bogard posted why he believed the dependency injection pattern appearing in the NerdDinner application was flawed.  I want to take the opportunity to say the pattern in NerdDinner really isn't that bad and I want to explain why.  Before I go on I will say that I entirely agree with Jimmy's thoughts on the pattern for my own code and you won't find the anti-pattern Jimmy describes in my code.

So why isn't the pattern that bad? I see Dependency Injection as generally having at least two major benefits:

  • Testability
  • Flexibility (most often achieved by using an IoC container)

The pattern under scrutiny in NerdDinner accounts for testability, of which I am a firm believer in, but lacks in flexibility.  If I had to rank the two items above, I would rank testability above flexibility.  Testability is a core tenet on which I stand for with the code I write.

Explain Again Why NerdDinner is "Flawed"

To recap here is the code from Jimmy's post:

   1: public class SearchController : Controller {
   2:  
   3: IDinnerRepository dinnerRepository;
   4:  
   5: //
   6: // Dependency Injection enabled constructors
   7:  
   8: public SearchController()
   9:     : this(new DinnerRepository()) {
  10: }
  11:  
  12: public SearchController(IDinnerRepository repository) {
  13:     dinnerRepository = repository;
  14: }

The first constructor, when called, "news up" a new DinnerRepository() and passes it into another constructor on the same object which is generally considered "poor man's dependency injection".  This pattern is considered bad (this an anti-pattern) because some, of which Jimmy is one, believe you shouldn't "new up" new objects this way, choosing instead to allow a container to inject the primal dependency.  The problem I have with this view is that for many applications a container is overkill.  Many applications will only have one concrete implementation of a class, so in many ways this constructor and the object creation could be seen as providing a sensible default to the application, allowing the consumer to create an instance without worry about what else the object needs.

But You Said You Don't Write Your Code that Way?

Absolutely correct, I don't write my code this way.  Why? I already have a container set up in my application and so to not use it would be foolish.  We also have a complex application/domain, sometimes with multiple concrete implementations of an interface.

I used to write code this way using this pattern. Really. I don't feel ashamed to say so. The reason we adopted the dependency injection (DI) pattern in the application where this overloaded constructor "anti-pattern" was used was because DI allows for testability, and as I have previously mentioned, this "anti-pattern" doesn't stand in the way of testing.

I further believe that most developers must make a certain progression on their own.  We can write and share our experiences but in the end every developer out there must some day be convinced in their own time. They must come to the conclusion on their own, like I did, that using "poor man's injection" will work for many many scenarios but will get ugly fast in others.

What's Really Wrong with "Poor Man's Dependency Injection"?

For simple applications/domain, typically not much (again, my opinion).  For complex domain the issue you will run into is maintainability/flexibility.  If you get to a complex domain and you use the pattern from NerdDinner you will someday have:

   1: public SearchController(new SearchService(new SearchLogService(new Logger()), new SearchRepository(new SessionBuilder()), new SearchResultFormatter(new FormatProvider())))

Ugly for sure.  This is why it's generally considered an "Anti-Pattern".  However for applications where the controller is the service-layer and controllers therefore use repositories, I would not be too concerned with the use of this pattern.

While Jimmy did a great job fixing the application, you first have to believe the application needed fixing.  Which of course, depends on context.  How big/complex is your application/domain?  Jimmy's application/domain is sufficiently complex as is mine, yours may not be.  For NerdDinner I believe the pattern was a suitable choice.


Posted 07-12-2009 10:07 PM by Tim Barcz

[Advertisement]

Comments

Jason Jarrett wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-13-2009 11:46 AM

You make some good points, and there are some cases where poor mans injection can be useful.

However personally I don't like the poor mans injection, it pushes the class past the SRP and makes changing things difficult down the road. If the DinnerRepository() all of a sudden needed an instance of something we would have to rip through all cases where we were poor man injecting (new DinnerRepository(...)) in the code base.

In this case I would prefer to create a simple factory to handle the creation of these objects. This way while the codebase is small it is still flexible in that I only have one place where I need to go to fix creations of (new Class(...)). At the point the factory becomes too complex and large to manage manually, it's simple as allowing the factory to use an IOC under the hood for creation of things.

Thoughts?

DotNetShoutout wrote Why There's Nothing Wrong With Dependency Injection in NerdDinner - Tim Barcz - Devlicio.us
on 07-13-2009 11:52 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

DotNetKicks.com wrote Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-13-2009 11:53 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Tim Barcz wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-13-2009 11:54 AM

@Jason,

"If the DinnerRepository() all of a sudden needed an instance of something we would have to rip through all cases where we were poor man injecting (new DinnerRepository(...)) in the code base."

How often does this really happen?  It absolutely can, but how often for NerdDinner type applications?

I generally agree with your points but mostly it all depends on the context of the application.

Andrew wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-13-2009 1:47 PM

I think some people forget who the Nerd Dinner is aimed at, it wasn't meant for those who already know what DI is.  The move from no DI at all to using a IoC Container is pretty large, and introducing that to people who have never done it before without the "Poor Man's DI" is often quite difficult.

Speaking only from personal experience, one of my tasks where I work is to teach a staff of about 20 things like DI, SOLID Principles, etc.   Most of these 20 have been working on the exact same projects for upwards of 7 years and have troubles picking up foreign concepts.  Without having Poor Man's, I don't think I could have 1) modified our existing code base without fear of breaking anything (since we have no tests what-so-ever) and 2) taught our people what DI is.

Derik Whittaker wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-13-2009 2:28 PM

As i am not normally a fan of 'Poor Mans Injection' but it does have its place.

Take for examle a time where you do not have an IoC container setup (yet) but you want to start using DI.  

You could simply go around and change all the code calling your object at one time... but this may be risky based on code size.

Or you could add in 'pmdi' and refactory slowly and with less risk.

No matter what you are trying to do the goal is the same, it is simply a matter of which route do you want to take.

Tim Barcz wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-13-2009 4:26 PM

@Andrew,

Right on!

Tim Barcz wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-13-2009 4:32 PM

@Derik,

I think the key to what you said is "...it does have it's place."

People generally forget this.  There IS a place for hand coded ADO.NET or Linq-2-SQL or in this case "Poor Man's Dependency Injection"

Hadi Hariri wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 1:21 AM

This demo is primarily focused on showing developers how to work with ASP.NET MVC. To introduce an IoC container could side-track the objetive of the excersise. That is the only justification in my opinion for using this approach to what you call Poor Man's DI or IoC.

In any application that uses DI, the effort of adding an IoC is so small that there really is no reason to not use it.

So in terms of NerdDinner not using it, to a certain point, justifiable. For someone that understands the concept and to not use it in a real application, IMHO, is not justifiable.

Chad Myers wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 2:54 AM

Since I have really learned a lot about StructureMap and advanced IoC, there's hardly a time where I don't use it anymore, even for simple utility projects.

I started out hard-coding everything and before long it became apparent that it was far more difficult than just using the tool. I realized much of the code I had written before learning IoC, specifically StructureMap, was way more convoluted and back-bending than necessary.

So I disagree with the statement that 'for many applications a container is overkill.  Unless 'many' apps are under 100 lines of code or something.  By the time you get a few 'new' statements in there on non-BCL types, you'll see the ROI on the container in no time.

Blog post forthcoming.

Chad Myers wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 2:58 AM

One more thing, sorry for the double-post here :)

Another reason why I feel Jimmy is right is that things appear easier with poor mans DI the FIRST TIME or AT THE TIME OF INITIAL WRITING.  It's the maintenance period and follow-on improvements that really start to show that 'poor man's' is seriously flawed and will severely bite you.

Eventually the double maintenance of two DI strategies will far more complicate things than just using the container in the first place.

Also, the graph starts getting unmanageable quickly.  

The 'only one concrete implementation' is a red herring because that's no reason not to do proper DIP.  That one concrete will likely have other dependencies, and they even more.

Eventually it becomes very difficult to manage the graph, so you either switch to the container entirely, or fall into bad practices and not DI everything.

I know I sound hard-line on this, but it's from years of experience pounding it into me that eventually you're going to end up full container or bad practice quasi-DI.  So you might as well go full container as soon as your app reaches even minor friction/difficulty.

Tuna Toksoz wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 7:18 AM

My only point, something I also mentioned on twitter, is that NerdDinner is a sample app that demonstrates MVC. One of the main points of MVC was to improve decouling, and it allows the use of containers.

Using MVC almost requires the use of IoC tool, and nerd dinner should have made use of it.

All those are my opinions and are subject to change.

Darren Cauthon wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 9:37 AM

I have to agree with Chad.  To make an analogy, I'd say that this "poor man's" DI is like a crack in the foundation of a home, and the programmer who writes it is like a homeowner who says "Oh, the crack is ok, because I know it's going to hold the weight anyway."  That may be true *today*, but it may not be true in the future when changes are made.  

Tim Barcz wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 10:35 AM

@Darren,

Not the greatest analogy because "Poor Man's Dependency Injection" is easily fixable after the fact (when it become necessary).  A cracked foundation, when repaired, is still weaker and the crack still visibly noticeable.

Tim

Chad Myers' Blog wrote Just say no to 'Poor Man’s Dependency Injection’.
on 07-14-2009 10:53 AM

For background, Jimmy Bogard originally posted about the ‘poor man’s dependency injection’ style used

Dan Swatik wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 11:49 AM

You know I don't get why everyone picks on that NerdDinner app it is what it is a sample, it wasn't meant to show propoer patterns and practices ...it was just meant to show off the MVC framework nothing more.

Just  like I forget what his name is did a review of the unit testing they did in Nerd Dinner again this was just a sample but this guy went on and on I almost wanted to reach through the screen and strangle him... note to people get sleep before you do a review of someone elses work. LOL

Chuck wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 11:53 AM

"They must come to the conclusion on their own, like I did, that using "poor man's injection" will work for many many scenarios but will get ugly fast in others."

You mean we should learn from our experience and understand the trade-offs of our design decisions? )

My experience: I used this technique on my current project and have had the fortune of maintaining it for a little over a year (which is rare). So far I've had zero problems with this approach. It's a medium sized project; our construction call graphs are relatively simple and don't change in different scenarios throughout the application. We've also not had the problem of frequently changing constructors. If we had pain in this area then I would consider moving to using a container.

Similar to Andrew's situation, our development team of 10 had 2 people who knew TDD and DI. I made the decision to not use a container in order to reduce the amount of new things people had to learn.

I'm not saying it's always applicable, however I disagree with the argument that you should never do it.

Tuna Toksoz wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 11:58 AM

@Dan Swatik

As long as one keeps the critisism at a specific level, those are normal. In my opinion, what a sample app says is that "this is how you use mvc". It is always easy to say "hey this is sample app". A person doesn't have to know about a best practice, but those critics have been made maybe hours after the release (not the ones here, i am pretty sure similar things have been said before). What makes it great would be when they change the code to take advantage of "good practices".

Tim Barcz wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 12:04 PM

I think there is something for targeting the audience.  NerdDinner wasn't an "Enterprise Sample App" it was an application talking about the framework (which has been pointed out several times now by various people).

We seem to, as developers, have a hard time letting go of the notion that every app must follow a rigid set of guidelines.  Which, quite honestly, is saddening.

I remember someone, me!, writing that an "IoC Container is not a feature of the application".  So far there have been three posts (at least) (Mine, Jimmy's and now Chad Myers) and others surely to come.  None talking about the functionality of NerdDinner but rather the use of IoC as a feature of the application.

Andrew wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-14-2009 12:22 PM

I'm not really sure why people seem to care so much about this.  DI is a concept, whether you use a IoC or hand roll it a la Poor Man's DI, its the concept that is important.

To use a horrible analogy, consider PMDI the weed of IoC contains, a gateway drug if you will.  Getting developers to move from a situation where they have zero DI, which by extensions means they have zero unit tests (they might think they do, but their unit tests always end up being more like intergration tests), to a state where they can mock/stub out classes and do real unit tests is about 90% of the battle.  Once they get comfortable with that, moving that last 10% to a full IoC is actually pretty easy.

One other thing I didn't mention in my previous post (but did mention in Chad's blog post on LosTechies) is that not everyone has a choice of using an IoC container.  I have been pushing for it since I started at my company 8 months ago but due to a variety of reasons, it's just not going to happen, at least not for some time (ditto for ORMs, but that's another story).  

So as I said in Chad's blog, give me PMDI or nothing, I choose Poor Man's every time.  It's just the reality of the situation that some of us live in.

Roberto wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-04-2009 4:26 AM

cool blog

Qilla wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-10-2009 11:34 AM

If you have to do it, you might as well do it right.,

Ethendanna wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-11-2009 2:13 AM

Excellent site. It was pleasant to me.,

Naucia wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-11-2009 4:18 PM

I bookmarked this link. Thank you for good job!,

Nydirasa wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-12-2009 6:47 AM

Very cute :-)))),

Welanna wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-13-2009 11:55 AM

It is the coolest site, keep so!,

Doctorset wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 11-20-2009 7:53 AM

This is the welcome page for the dentaldoctor.us Association web site.

Dietroly wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 11-20-2009 8:52 PM

This is the welcome page for the dietguidance.us Association web site.

Christmasmas wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 12-24-2009 5:55 PM

Can child christmas gift make parent can-child-christmas-gift-make-parent.christmasmas.com

Javier G. Lozano wrote What is the purpose of MVC Turbine?
on 12-31-2009 1:14 AM

What is the purpose of MVC Turbine?

devlicio.us wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 03-28-2011 6:02 PM

Why there s nothing wrong with dependency injection in nerddinner.. He-he-he :)

devlicio.us wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 04-22-2011 7:07 AM

Why there s nothing wrong with dependency injection in nerddinner.. Great! :)

Patrick Szalapski wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 05-06-2011 1:56 PM

>"If you get to a complex domain and you use the pattern from NerdDinner you will someday have:

  1: public SearchController(new SearchService(new SearchLogService(new Logger()), new SearchRepository(new SessionBuilder()), new SearchResultFormatter(new FormatProvider())))"

I though the problem with the SearchController was in the default constructor.  Could you elaborate how "real" DI fixes the above code?

devlicio.us wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 06-02-2011 5:59 PM

Why there s nothing wrong with dependency injection in nerddinner.. Awesome :)

devlicio.us wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 06-04-2011 6:20 PM

Why there s nothing wrong with dependency injection in nerddinner.. Keen :)

nwk3 xxx 1vty wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-02-2011 12:04 AM

Why there s nothing wrong with dependency injection in nerddinner.. Corking :)

cheap seo services wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-18-2012 11:49 AM

irjg37 Thanks again for the blog.Really looking forward to read more. Cool.

crork wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 11-05-2012 12:19 AM

EtxRtP I really liked your article post.Thanks Again. Will read on...

Social Bookmarking Service wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 11-24-2012 11:39 AM

O3skv6 Thanks so much for the blog article.Really thank you! Cool.

social bookmarking dofollow wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 01-18-2013 11:16 PM

RT07G1 Thanks a lot for the blog.Much thanks again. Want more.

buy imitrex online wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 02-15-2013 6:49 PM

xCOZXr Great blog.Much thanks again. Keep writing.

buy clomid wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 02-28-2013 10:37 PM

JeM8qo Enjoyed every bit of your blog post.Much thanks again. Great.

buy social bookmarks wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 03-23-2013 7:32 PM

DGctHJ Thanks again for the blog post.Much thanks again. Fantastic.

buy social bookmarks wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 04-19-2013 2:05 PM

TzKq09 Im obliged for the article post.Thanks Again. Much obliged.

social bookmarking service wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 04-28-2013 3:14 AM

TIsq3l I think this is a real great blog post.Much thanks again. Keep writing.

digital camera guide wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 05-14-2013 10:12 AM

d99Scu Thanks again for the article post.Really thank you! Want more.

cheap social bookmarks wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 06-19-2013 6:02 PM

odEed8 Awesome blog.Much thanks again. Will read on...

news and many more wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-04-2013 8:45 AM

3u5I4H Muchos Gracias for your blog post.Really looking forward to read more. Awesome.

mcafee promo code wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 07-12-2013 7:01 AM

Useful information shared..Iam very happy to read this article..thanks for giving us nice info.Fantastic walk-through. I appreciate this post.

best news wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 08-02-2013 12:26 PM

Im grateful for the post.Really thank you! Want more.

amazing news wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 08-02-2013 5:38 PM

stx2HS Im grateful for the blog post.Really looking forward to read more. Cool.

awesome moldavian news wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 08-05-2013 1:10 AM

Uh0soo This is one awesome article.Really looking forward to read more. Really Cool.

awesome links for you wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 08-19-2013 10:36 AM

vpIpmN I value the blog article.Thanks Again. Cool.

awesome links for you wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 08-20-2013 12:37 AM

ayc1Ts A big thank you for your article post.Much thanks again. Fantastic.

great seo service wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 09-04-2013 12:53 AM

g16sCW wow, awesome blog article. Keep writing.

online business wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 09-11-2013 6:21 PM

30Ron4 Im thankful for the blog article.Really looking forward to read more. Will read on...

awesome link building wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 09-24-2013 6:33 PM

ueGf3W I cannot thank you enough for the article post.Much thanks again. Want more.

best linkbuilding wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-01-2013 6:00 AM

KFH92D Major thanks for the post.Much thanks again. Will read on...

best link build wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-16-2013 2:55 AM

syrwtk Thanks a lot for the blog article.Really thank you! Much obliged.

take a look at it! wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 10-31-2013 6:13 AM

CTDS4g Thanks for the article post.Thanks Again. Keep writing.

seo service wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 12-15-2013 5:03 AM

RbTCYl Very informative blog post.Really looking forward to read more. Really Cool.

stunning seo guys wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 01-07-2014 10:55 PM

LWKnEQ Thanks for the post.Really looking forward to read more. Really Great.

nice seo guys wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 01-17-2014 8:34 AM

1PiJF9 Major thankies for the post.Much thanks again. Want more.

check it out wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 02-08-2014 2:29 AM

r5Vw9U Really informative blog article.Thanks Again.

buy_viagra wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 02-20-2014 1:25 PM

Hello!

,  ,  ,  ,  ,

seo for cheap wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 03-22-2014 2:32 PM

LM6oWz Very good blog.Really thank you! Awesome.

check it out wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 03-25-2014 8:49 AM

9J2GyD I am so grateful for your blog.Really thank you! Great.

nice seo guys wrote re: Why There's Nothing Wrong With Dependency Injection in NerdDinner
on 04-01-2014 6:00 AM

9LbDtS Im obliged for the blog article.Much thanks again. Awesome.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)