in

Fort Worth .NET Users Group

Dot Net Tricks

December 2008 - Posts

  • Found some good code today

    I'm hoping this won't offend any of you out there, but most of us developers write crappy code.  I'm not fully sure why this is, but even if the database isn't a steaming pile of horse poo, the code usually is.  There's often a lot of code duplication, methods and property names that don't make much sense, large, "god-like" classes, massive amounts of nested "if" or "case" statements, etc.

    I'm not even getting into ORMs, design patterns, DI, Loose Coupling and High Cohesion, Unit Tests or anything like that.  Many programmers don't follow basic, good, structured programming tactics.  You have to walk before you can run but it often seems like a lot of programmers, even those with 10+ years of experience are still crawling.  My screaming about database normalization at Telerik is an example of this, and we just ran into another vendor with few relationships in their database, zero constraints and a whole lot of duplication.  Fortunately we do not have their source code (although I hear its in VB.NET.)

    But enough of that.  Today I found some REALLY GOOD CODE.  Its not perfect--no code is--but its really high quality.  It comes from a little product that always has a soft spot in my heart, the Wilson O/R Mapper.  This was the first ORM I really liked.  You should pull it down and take a look at the source code. It used to be a commercial product but Paul Wilson open sourced it some time ago.

    Even though NHibernate is our standard right now and does a lot of great things, I've been toying.with the idea of writing a new ORM or extending an existing one.  NHibernate has a lot of complexity, and as Robert pointed out to me, its difficult to get working with a remoting or WCF type architecture for smart clients.  NHibernate also has a lot of other warts, including a sometimes ugly API that is dated and based on its java sibling, complex mappings, surprises when it comes to bidirectional relationships (those of you having to create a method that looks something like this: Customer.AddOrder(order) know what i'm talking about...) and other nastiness.  Its probably one of the best ORMs out there but by no means perfect.  EF still isn't out as far as I know and has a lot of growing up to do.  So i've been thinking of working on my own ORM, without starting from scratch.

    I could try extending the NHibernate codebase, but its plain ugly.  Many of the failings I just mentioned above live within the NHibernate source.  I'm not sure if this is NHibernate showing its age or what, but I'm afraid to try to alter anything within it.  Everything is big, complex and hairy.

    So imagine my surprise when I downloaded the latest source code to Wilson ORM.  Small, concise methods.  Highly cohesive classes.  Appropriately named classes, methods and properties.  Good use of interfaces.  Minimal duplication.  Everything is broken up into logical chunks.   In short: "GOOD CODE".  To be fair, Wilson doesn't do everything that NHibernate or some of the other mappers do, but even still, the codebase and API simplicity is impressive.  Its so easy to be bitter and jaded about bad programming, so I thought it appropriate to say "well done" to Paul Wilson and the other developers that have worked on it.

    I encourage you to download the thing just as a learning experience. 
  • Die Code-Behind DIE!!!

    As mentioned in previous episodes, my team is standardizing on the ASP.NET MVC Framework for web development.  One thorn in our sides has been that by default, Visual Studio would create a code-behind for your views automatically, and if you wanted a view that used a strongly typed model, such as ViewPage<Person> or ViewPage<ProductCollection> then you had to create a code-behind file.  There were CLR hacks to do this in the code in front, but they were just awful.

    In webforms, code-behind made sense, in MVC not so much.  I think they tend to encourage developers to write code in the old webforms way, and not use the controllers and helper methods as much.  One of the reasons to move to MVC is to return to simplicity--no page events, no controls, no viewstate.  Code-Behind is a blemish on that simplicity.

    Well the nail has officially been driven into the coffin for our old friend code-behind.  In the next version of MVC, it can go away completely:

    http://weblogs.asp.net/scottgu/archive/2008/12/19/asp-net-mvc-design-gallery-and-upcoming-view-improvements-with-the-asp-net-mvc-release-candidate.aspx

    You can still add code-behind if you are perverted, twisted, abomination of a developer, but its no longer there by default.

    DIE Code-Behind!  DIE!!!

    (oh and normalize your fucking databases.)
  • For the love of God, Normalize you databases!


    Despite that stupid presentation about "normalization is for sissies" that went around the net for a while, I'm very pro-normalization. Normalization and the standard Third Normal Form (3nf) simplify data management and application development greatly.  This is especially true when writing object-oriented code or using an ORM, but I normalized long before I knew what an object was.  For SOME reason, there's developers still out there that choose not to normalize.  I ran into this problem quite a bit when I worked for a certain online matchmaking company.  They had a lot of denormalized tables and it made the application more complicated, although that was the tip of the iceberg in the IT and general mismanagement at that company.  I won't say what company it was except that it was a truly interesting experience.  In a bad way.

    Again, denormalization has reared its ugly head today.  This time with a company and product I WILL mention, Telerik's Sitefinity.  Overall, Sitefinity has some good features but upgrading from one version to another is always a pain.  Today we ran into an issue that that we blew hours on and could have been easily avoided with a little 3NF magic.  Below is the forum post to Sitefinity.  Its a bit of a rant, but I want to illustrate to all you other developers the kind of extra problems you run into when not normalizing.  Note that I DO say there are times for denormalization, but its one of those cases where you have to know the rule in order to know when to break it.

    Posted at:
    http://www.sitefinity.com/support/forums/support-forum-thread/b1043S-bthhde.aspx

    We did a 3.x to 3.5 upgrade this week on one of our existing websites, and ran into some pain.  On of our other developers spent 4 hours working on it, which in fairness is partly because we have our own customizations in the site.  However, he got stuck on one particular error.  The error could have easily been avoided if you would just NORMALIZE YOUR DATABASE.  Its really not that hard and would help us developers greatly.  I'm not sure if its your developers that don't normalize certain things or if its Nolics itself, but not normalizing means more room for these types of errors and more data that has to be touched when somethings changed.  Below are the steps I as the lead developer had to go thru to debug and correct this problem:

    So the other developer was getting this error related to the Sitefinity upgrade that said “Key not found for value UpcommingEvent.”

    "Upcomming" was misspelled so i figured the error was related to the Sitefinity developers correcting the spelling.

    Looking through the stack trace, I saw it was trying to parse this value from into an enum and not finding that string in the enum thus throwing the error.

    Since all the code had been completely replaced by the new version (3.5) I assumed the problem had to be in the database.

    There are like 100+ something tables in Sitefinity, so going thru them one by one was out of the question.

    I opened up sql profiler, ran the page again and collected all the generated queries to the database from sitefinity.

    Nothing in the queries mentioned “UpcommingEvent” so instead I ran all the queries that profiler found and looked at the results.

    I converted the query results from grid view to text view in sql management studio.

    I then did a find for UpcommingEvents, and found the text!

    I found the query that got that result to find the table and column holding that event, something like "sf_cmscontrolproperty" and "value".

    I did a LIKE search on that table and column to find all the records that had “UpcommingEvents”.  19 records had this text in it!

    Not knowing what the right value was to put in there, I did a search in vs.net in object browser for anything that had “Upcoming” (spelled correctly) in the hopes I would find an enum with this value and that this would be the correct value.

    Sure enough there WAS an enum and it had 3 values, something like PastEvents, CurrentEvents, UpcomingEvents (spelled correctly.)

    I copied the exact enum value into sql query analyzer and updated the 19 records from “UpcommingEvents” to “UpcomingEvents”

    I ran the site again, and it was fixed.

    This took over an hour.

    If the database had been normalized, with just the value of the enum (the integer) in the database, this could have been avoided.  You could have changed the names of the enums without hurting the data at all, as long as you didn't change the underlying values.

    Anytime you see repeating data (in this case "UpcommingEvents" your breaking normalization and creating work for yourselves and/or your customers.  3NF has been around for a long time, I'm not sure why so some people choose not to use it when it prevents a slew of problems.  Its okay to denormalize certain data thats non-authoratative and can be recreated from normalized data (such as for reporting) but this wasn't the case.

    Thanks,
    Craig

  • TDD + Resharper Payoff - Refactoring

    So the project i mentioned the other day in my last post has had minimal need for refactoring.  Part of that is because I'm such a super badass developer who always gets things right the first time (yeah right), and part of it is that the project is small enough and young enough that there isn't need for massive changes yet.

    But today, there was some stuff that had been bugging me, so I decided to do some cleanup, aka refactoring.  Specifically:

    • I changed the names of 4 classes.
    • I changed the names of a bunch of interfaces for the above classes.
    • I changed the name of a persisted property.
    • I changed the field in the database for that property.
    So I made these changes and Resharper took me 50% of the way there towards keeping my existing functionality intact.  It renamed all the references, strings, my NHibernate XML Mapping files, dictionary names, and all sorts of things.

    But then I ran my unit tests.  I found all kinds of things broken from the refactoring.  Within minutes i had all this fixed and working properly.  Finally I had to do a quick regression test thru the web layer, and found a few things here and there that had to be fixed.  This was only necessary because I haven't really tried creating Unit Tests for my Views, although apparently other people have.

    In another, testless, project this would have taken a lot longer, in the realm of a few hours instead of only minutes.  But this was only a small project that i've been working on and off for a few months.  Imagine something on the scale of a 6 month project or a 2 year project with multiple developers. 

    I'm starting to get hooked.  TDD hasn't really started to pay off until now.   If you care about refactoring, you owe it to yourself to really try TDD.



  • My current architecture

    For the six or seven of you in the world that actually read my blog, you've noticed that i've been pretty quiet lately.  So while i'm chomping down breakfast before work, I thought I'd give you a rundown on what i've been doing lately.

    I'm working on a medium size project that eventually may blow into something larger, which given the current economy would be great.  Its a front facing, product catalog, type web project, but there will soon be a comprehensive suite of admin tools, reporting, integration with other systems, etc.  So I'm trying out a new (for me) architecture for this site because I can tell it may grow into something much bigger than it already is.

    So without further adieu, here is my current architecture and toolkit for this project.

    1. ASP.NET MVC - Microsoft should have done this years ago.  Its a refreshing return to simplicity.  I've already written about why webforms suck.  So if you haven't checked out MVC you should.
    2. NHibernate - Its not perfect, but if you are practicing Domain Driven Design and want to build objects that have little or no coupling to persistence logic, this is the defacto standard ORM among open sources ORMs.  I tend to shy away from the HQL as there always seems to be something missing from the language, but the criteria classes work nicely.  Of course, you can always drop back down to HQL or SQL and there's a LINQ to NHibernate in the works.  Overall, I've been pretty happy with it.
    3. DDD - First off, I'm not a domain driven design expert.  But I'm trying to incorporate it as much as possible into this project.  I have domain objects for domain logic, repositories for data access (which use NHibernate) and service objects for other business logic that doesn't belong to a single domain object. 
    4. Service Objects - While I'm on the DDD topic, i've started using "services" a lot more, which is a DDD concept.  What's an example of this?  Well, I have a UserRegistration service that takes a user object, saves it using a UserRepository, and sends an email notification using an EmailService which sends the email.  I didn't want all that logic in my controller (and you webforms people shouldn't put that stuff in the code behind!), so I refactored it into a UserRegistration service.  I also didn't want it in any domain object, because it needed to coordinate domain logic, persistence logic and the email service. I have another situation where I have a purchase inquiry where the user submits a PurchaseInquiry object that has a reference to the user, and a reference to the product they're interested in and a few other fields and saves it to the database.  But I also need to send an email and integrate into a third party CRM.  So I have a PurchaseService that saves the PurchaseInquiry (again using a "PurchaseInquiryRepository" ), sends the email using an email service and then calls into the CRM service to do the integration.  I've really been pleased with how  this "service layer" works in these complex scenarios and keeps this logic in the business layer where it belongs. I don't make service object for everything--just the places where coordination between different domain objects, services and repositories is necessary.  Also, you want to avoid the dreaded "anemic domain model" that can be a temptation when using services.  My domain objects still have a lot of behavior, but they don't cross network boundaries into outside systems (such as database, email, web services, etc.)  For these sort of thigns, I put the logic into services.  I'm not sure this is the "official" DDD way of using services, but this has been very useful to me.
    5. JQuery - So we're not using webforms, so what do we use for controls?  Although you can use controls in MVC, part of the extra complexity in traditional webforms came from controls that contained server side and client side code (C#, Javascript, CSS) and tried to package them all together.  Styling and customization was a constant issue with many of the controls I've used and many of the useful things that controls did (such as maintaining state) no longer work in MVC's non-postback environment.  Fortunately Jquery has a suite of UI widgets, called JQuery UI and you can use these almost like server controls--you just add markup and a tiny bit of javascript to wire them up and you have tabs, menus, etc.  I'm very pleased with JQuery so far.  Ajax is especially simple.  With asp.net ajax, you have to have that stupid script manager tag, (but ONLY ONE script manager tag or you get an error), and the web.config settings, and the tags in the page to set up specifically what you are doing.  With JQuery, i write 2-3 small lines of code and they can call a controller method in MVC directly, get the results and update any part of my page. 
    6. TDD + NUnit - I'm trying out this whole Test First methodology. I've done some TDD in the past but never went gung-ho the way I am with this project.  I have integration tests for all my data access and unit tests for domain objects, services and controllers.  Eventually I'm going to swap this out with MBUnit which is supposed to be more feature rich, but I started with NUnit because that's what I know.  So far, I can definitely see SOME of the benefits of doing Test First development.  It definitely makes refactoring easier, but I don't see a massive drop in defects.  I usually code in a somewhat loosely coupled and OO manner and don't normally have dozens or hundreds of bugs in my projects, but on the other hand the projects i've done lately have been pretty small.  Maybe as this thing grows, TDD will shine even more.  Right now its taking some getting used to, and all the "extra" code is annoying me.  I'm also using Rhino mocks for mock objects, but as this was a huge learning curve for me I'm not ready to write about it now.
    7. General "Onion Architecture" - Much of what I've talked about above comes straight from Jeffrey Palermo's Onion Architecture and his Agile Bootcamp class.  So I'm also doing things like loose coupling between layers using Dependency Injection and Structuremap.  If you haven't looked at DI, you should.  The learning curve is very minimal and changes very little about how you write your code.  A few interfaces here, a constructor there, a tiny bit of configuration and poof!--Loosely coupled architecture!  Okay there's a little more too it than that, but TDD by far is a much larger paradigm shift.  With the DI, I've got my NHibernate mappings and repositories in a separate project that gets hooked up to my domain layer at runtime, so the implementation of the ORM and data access stuff is completely decoupled from the rest of the application.  
    I thought about scattering links to all this cool stuff in my post, but instead I'll just put it all here at the bottom in one convenient place:

    ASP.NET MVC
    http://www.asp.net/mvc/

    Also see MVCContrib for other MVC goodies:
    http://www.codeplex.com/MVCContrib

    NHibernate
    http://www.hibernate.org/

    Domain Driven Development
    http://domaindrivendesign.org/

    There's also the classic book by Eric Evans:
    http://domaindrivendesign.org/books/index.html

    But i cheated and got the cliff notes version:
    http://www.infoq.com/news/2006/12/domain-driven-design

    JQuery and JQuery.UI respectively:
    http://jquery.com/
    http://ui.jquery.com/

    NUnit and MBUnit:
    http://www.nunit.org/index.php
    http://www.mbunit.com/

    Onion Architecture
    http://jeffreypalermo.com/blog/the-onion-architecture-part-1/


Copyright FWDNUG 2008
Powered by Community Server (Commercial Edition), by Telligent Systems