Posted on July 14, 2009 17:02 by swilliams

I like frameworks. I spent far too much time in my programming infancy reinventing the wheel, and I don’t want to ever have to write more code than I have to again. Thus, I like relying on frameworks to take the tedium out of certain parts of the craft.

However, a problem arises when you don’t know what that framework is doing. Recently I spent many hours tracking down one specific bug that needed a single line changed to fix. In this specific case it was in an ASP.NET WebForms app. A <button> tag was used to make some fancy ajaxy calls via jQuery and PageMethods and the onclick event. The problem was that the form that was supposed to be displayed only appeared for a few seconds, then vanished again.

I poured through the code, set many breakpoints, broke out both Firebug and the Safari debugger (both proved useless due to the actual problem). Despite all of this, I still couldn’t figure out what the heck was going on. Finally, after I was ready to jump off the parking garage, the light bulb clicked on.

The <button> tag behaves like <input type=”submit” />; it sends a postback. And since the form was wrapped in an UpdatePanel, it was executing both the jQuery ajax, as well as the ASP.NET ajax, which were clobbering each other. In Firefox, the jQuery code finished first, and was then overwritten by the Page_Load from the UpdatePanel, causing our freshly rendered form to go away.

Changing the <button> to <input type=”button” /> fixed things. There are plenty of other fixes for this issue, but that’s what we used.

ASP.NET WebForms and ASP.NET Ajax like to abstract many of the “complicated” web development concepts away from the developer. I’m not going to comment on whether this is a good or bad thing, but it can present issues if you are using some mechanism and are not aware of what is going on under the hood. These problems usually don’t even manifest until late in a project- when the bosses are breathing down your neck and wondering why the app isn’t finished yet.

Does this mean we should abandon frameworks entirely and code everything in C (or assembler)? Certainly not, but if you are going to use that extra super duper happy UpdatePanel, you had better know what it is going to do to everything inside of it.

I like frameworks. I spent far too much time in my programming infancy reinventing the wheel, and I don’t want to ever have to write more code than I have to again. Thus, I like relying on frameworks to take the tedium out of certain parts of the craft.

However, a problem arises when you don’t know what that framework is doing. Recently I spent many hours tracking down one specific bug that needed a single line changed to fix. In this specific case it was in an ASP.NET WebForms app. A <button> tag was used to make some fancy ajaxy calls via jQuery and PageMethods and the onclick event. The problem was that the form that was supposed to be displayed only appeared for a few seconds, then vanished again.

I poured through the code, set many breakpoints, broke out both Firebug and the Safari debugger (both proved useless due to the actual problem). Despite all of this, I still couldn’t figure out what the heck was going on. Finally, after I was ready to jump off the parking garage, the light bulb clicked on.

The <button> tag behaves like <input type=”submit” />; it sends a postback. And since the form was wrapped in an UpdatePanel, it was executing both the jQuery ajax, as well as the ASP.NET ajax, which were clobbering each other. In Firefox, the jQuery code finished first, and was then overwritten by the Page_Load from the UpdatePanel, causing our freshly rendered form to go away.

Changing the <button> to <input type=”button” /> fixed things. There are plenty of other fixes for this issue, but that’s what we used.

ASP.NET WebForms and ASP.NET Ajax like to abstract many of the “complicated” web development concepts away from the developer. I’m not going to comment on whether this is a good or bad thing, but it can present issues if you are using some mechanism and are not aware of what is going on under the hood. These problems usually don’t even manifest until late in a project- when the bosses are breathing down your neck and wondering why the app isn’t finished yet.

Does this mean we should abandon frameworks entirely and code everything in C (or assembler)? Certainly not, but if you are going to use that extra super duper happy UpdatePanel, you had better know what it is going to do to everything inside of it.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on April 9, 2009 14:37 by bward

Had a little bit of time on my hands yesterday, so figured browse through reflector.  If you haven't heard of it, here is a description:

.NET Reflector enables you to easily view, navigate, and search through, the class hierarchies of .NET assemblies, even if you don't have the code for them. With it, you can decompile and analyze .NET assemblies in C#, Visual Basic, and IL.

It's a great learning tool.  Go ahead, take some time to snoop around.  You'll be surprise on what you learn!  That day, I decided to check out the HybridDictionary.  This class is a specialized collection that initially uses a ListDictionary, which is recommended for collection that contain 10 items or less, then migrates over to a HashTable

Everything that I have ever heard gave me the impression that the HybridDictionary migrates over to a HashTable once the item count is equal to or greater than ten.  This is NOT true.  Examine the following code from reflector.

  1. public void Add(object key, object value)
  2. {
  3.     if (this.hashtable != null) {
  4.         this.hashtable.Add(key, value);
  5.     }
  6.     else if (this.list == null) {
  7.         this.list = new ListDictionary(this.caseInsensitive ? StringComparer.OrdinalIgnoreCase : null);
  8.         this.list.Add(key, value);
  9.     }
  10.     else if ((this.list.Count + 1) >= 9) {
  11.         this.ChangeOver();
  12.         this.hashtable.Add(key, value);
  13.     }
  14.     else {
  15.         this.list.Add(key, value);
  16.     }
  17. }

 

If I am reading this correctly, which I like to think I am, nine is the magic number, not ten. Once the list collection reaches a count of nine, ChangeOver() is called. Here is the code for that method.

 

  1. private void ChangeOver()
  2. {
  3.     Hashtable hashtable = default(Hashtable);
  4.     IDictionaryEnumerator enumerator = this.list.GetEnumerator();
  5.     if (this.caseInsensitive) {
  6.         hashtable = new Hashtable(13, StringComparer.OrdinalIgnoreCase);
  7.     }
  8.     else {
  9.         hashtable = new Hashtable(13);
  10.     }
  11.     while (enumerator.MoveNext()) {
  12.         hashtable.Add(enumerator.Key, enumerator.Value);
  13.     }
  14.     this.hashtable = hashtable;
  15.     this.list = null;
  16. }

 

There you have it. This is a small example of what you can learn by simply downloading reflector and browsing through the code.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on December 12, 2008 13:57 by swilliams

I kind of left my last post on this subject dangling, but now I'm ready to come clean.  I was proceeding merrily along, removing the tightly coupled LINQ to SQL generated code into something nice and loose, but ran into some serious snags when trying to update the database objects that had joins associated with it.

The code became more and more unwieldy; I was creating extra loader classes for longer inheritance chains, and more and more abstractions to get everything to work properly. At some point, a little voice in the back of my head started saying, this is supposed to be EASIER? Finally it reached a point where it simply did not appear that I would be able to meet my goal of defining my class models separately from LINQ to SQL's generated ones.

So, I gave up and let the idea die while I focused on other things. Occasionally I did revisit it, but only met with the same conclusion.

About a month ago I became interested in the new ASP.NET MVC framework. Rob Conery has been publishing a series of videos that detail his process of creating an online store. While watching those, I realized that he was implementing the very idea that I had wanted to do here. And amazingly, the code to do it was surprisingly simple and small.

After studying it and poking around, here I am today with the answer! It lies in what Rob calls the Repository pattern. It boils down to this: you have your model classes defined somewhere (in the sample app, I'm using LinqExample.Core), an IRepository interface that states the methods that will interact with the database, and the implementation (LinqRepository here). Rob goes on to create a Service class that sits between the UI and Repository, but for this example, I'm leaving that out.

public interface IPersonRepository {
    IQueryable<Person> GetAll();
    Person GetSingle(int personId);
    IQueryable<TpsReport> GetReports(int personId);
    
    int SavePerson(Person person);
    int SaveReport(TpsReport report, Person forThisPerson);
}

This also makes testing easy. I can cook up a TestPersonRepository that returns dummy data, allowing any UI testing to avoid touching the database.

Next, we create the implementation of this interface using LINQ to SQL. Add the .dbml CropperCapture[13] file and drag the two tables onto the workspace as you would normally. The key part here is to change the Context Namespace and Entity Namespace to something other than the default (an empty string). I used LinqExample.Data.Repository. This has the effect of namespacing each generated class. Thus, they will not conflict with the model classes we have already defined.

Our example actually looks similar to what I laid out in Part 3, however I do not use the Entity types for the joining objects, but rather IQueryable<T>. This allows a lazy evaluation of the objects, and let's LINQ to SQL's binding work better. Additionally, I reverted all of the properties in the classes to the basic auto-properties that C# 3.0 brings us.

public class Person {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public IQueryable<TpsReport> Reports { get; set; }
}

The key piece from Rob's code is how he pulls the data using LINQ to SQL. Rather than just returning the auto-generated classes, he selects the actual Person or TpsReport class and the initializers to populate them:

public IQueryable<LinqExample.Core.Person> GetAll() {
    var people = from pe in this.db.Persons
                 select new Person {
                     Id = pe.id,
                     FirstName = pe.fname,
                     LastName = pe.lname,
                     Reports = this.GetReports(pe.id)
                 };
    return people;
}

At this point you may be thinking "All you did is create a class and just do a bunch of right/left property setting." While that is true (and the right/left bit does get tedious), it does more than that by return IQueryable<T>.

Returning as an IQueryable<T> has an extra advantage of letting you do further queries without having to throw away parts of the initial return set. Thus, if you chose to implement the Service layer, you could keep GetAll() in the Repository implementation, and have GetSingle(), GetWithLastName(), and others in the Service assembly.

If you returned an IList<T> instead, you would need to call ToList(), which would run the whole query right then, and forsake all the lazy evaluation benefits from IQueryable<T>. Of course, you may want to do that, but that is what the Service Layer is for.

Updating the database is not quite as simple, but doesn't involve black magic either. The gist of it is to check to see if this is an update or an insert call, and to perform accordingly. Here is SavePerson(), but SaveReport() is very similar

public int SavePerson(Person person) {
    using (Repository.LinqExampleDbDataContext saver = new Repository.LinqExampleDbDataContext()) {
        Repository.Person pe = saver.Persons.SingleOrDefault(p => p.id == person.Id);
        bool isNew = false;
        if (pe == null) {
            isNew = true;
            pe = new Repository.Person();
        } 
        pe.fname = person.FirstName;
        pe.lname = person.LastName;
        if (isNew) {
            saver.Persons.InsertOnSubmit(pe);
        }
        saver.SubmitChanges();
        return pe.id;
    }
}

And, you're done! This is a little easier to swallow than what I had going in Part 3, no XML to muck around with, and is far simpler than the code soup I was cooking up before abandoning that approach.

Should you decide to go with another technology, be it the Entity Framework, NHibernate, or even a non SQL Server database, you would only need to create an IRepository implementation for that particular framework/database. It can be tedious for large quantities of tables, but that is the price you might have to pay for loose coupling and a friendlier design. Of course, you could refactor that to automatically set properties through Reflection or something, but that is another article altogether.


Source code for this post is located here.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on October 20, 2008 10:19 by swilliams

I've recently taken to learning about Microsoft's Team Foundation Server. It has a good API and I wanted to see if I could do something similar to what I did with SubVersion and Python. So, I spent the weekend getting everything up and running.

For comparison's sake, here is how you install and create SubVersion repositories in a commonly used development environment:

  • Download SubVersion.
  • Install it.
  • Don't like the command line? Download TortoiseSVN and install it.
  • Right click somewhere and select "Create repository here..."

Four steps (with two being optional). The biggest problem I had with the TFS install was that it took far too many hoops to jump through that I almost considered giving up. Fortunately, I'm stubborn and pushed through.

Firstly, TFS can install on a domain-less network (like what I run at home), but I figured that the most common implementation is on a domain, so I created a new VM and installed Windows Server 2008 for the Domain Controller.

[It should be noted that this isn't necessarily a good differentiation from the SubVersion install, since the best practice would be to install SubVersion on a separate server, preferably Linux based.]

Once the Domain Controller was set up, I installed SQL Server 2008 since that is what TFS uses as the data store. This too went without a hitch.

However, upon starting the installer for TFS I was greeted with a message stating that it cannot be installed on a Domain Controller, or a server running "Enterprise" applications (Exchange, BizTalk, etc).

I'm assuming this is for security reasons, which brings me to a grumbling point I have with TFS: there is no "Developer Version." It must be installed as if for a production environment. I understand that Microsoft wants to ensure that their customers aren't doing something stupid and opening themselves up to attacks, but this is solely on a virtual environment that will be inaccessible from the outside. SQL Server has a developer version that can be installed on a client OS, why doesn't TFS? And further, you can install SQL Server and IIS on a Domain Controller, which is already a bad practice, why not TFS?

Anyways, after some mild cursing I spun up another Virtual Machine for another Server 2008 installation. Fortunately I have 4 Gigabytes of RAM in my workstation, though at this point I was wondering if I should convince my wife that upgrading to a quad core processor would be worth it.

Eventually, the second server was up and connected to the domain. Installed SQL Server 2008 again and went to install TFS. This time I got an incredibly worthless error message that annoyed me enough that I Twittered about it. It effectively said that there  was an error, but it was so dire that it couldn't be displayed in a dialog, so you should check the logs, but there wasn't even a link to where those were. I briefly looked in the filesystem, but didn't see anything obvious. Hindsight says that I should have checked the Event Viewer, but I hate digging through that and I found my solution regardless.

I suspected I had missed a pre-req and consulted the documentation again. Herein my second grumbling point. The documentation for TFS is a .chm file. I hate these things. They're essentially hypertext viewers, but without any benefits from modern browsers, like tabs. I would have loved to have opened a bunch of different tabs for each page I was looking at, but was stuck with a Single Document Interface.

The missing pre-requisite was IIS. Whoops, my bad. Installed that lickety split and fired up the installer. Again, I understand that the target market for TFS is larger development groups with 10,000+ users, and a powerful web server is required for that, but for tiny groups, why not just include Cassini or something similar?

This time I did not get the stupid error, but failed when it scanned for the required pre-requisites (somehow IIS was needed to get to this part). There were a few errors regarding my SQL Server install, it needed Analysis Services, Reporting Services, and a couple of other things. Whoops again. It also said that my version of SQL Server was incompatible, though at the time I figured that this was the catch-all error to display when there were other problems too.

Went back to the SQL Server 2008 installer and added everything except the Management Studio and on-line books. See my similar bone of contention with needing IIS for enterprisey development, when something tiny and embedded would be awesome for me.

Again, my version of SQL Server was incompatible. More cursing, though a little stronger this time, because I knew that SQL Server 2008 would work with TFS 2008. After sifting through the documentation some more, I found that SQL Server 2008 will work with TFS 2008 Service Pack 1. Of course, there wasn't a download available for an installer with both, so I had to merge the service pack into the base installer (I would love to link to a webpage detailing this, but again, .chm file).

Finally, I was able to install TFS 2008. TFS also requires SharePoint (why?), but one good thing about the 2008 version is that it will install SharePoint Services 3.0 automatically for you. This is good because if you think this post is just a rant in disguise, it's cupcakes compared to SharePoint. My memory may be faulty but I believe that TFS 2005 did not do this for you, so 2008 gets high marks here.

This is starting to seem like a Shaggy Dog story, but that was basically it. My install wasn't exactly a standard one; I should probably keep SQL Server and TFS on separate machines, but I only have so much memory for these resource intensive virtual environments.

The moral here is that this install experience borders on unacceptable. Yes there were some user errors, but those could all have been taken care of in a Developer Version. SubVersion only features Source Code Management, but in my experience most developers only use TFS for that as well (which is sad since it offers much more). Installation is the very first thing that people see when they actually use your app, and it will color their opinion throughout the rest of the experience.

Installing TFS requires the developer to dig through mediocre documentation. Developers hate reading documentation, when things should "just work." And installers need to be simpler, especially when they don't always have to be Enterprise level.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on June 3, 2008 10:25 by cjenner

If you haven't read this article on InfoWorld I strongly suggest it -   The 30 skills every IT person should have .

I think my favorite is no 23 -"There is no such thing as a dumb question, so ask it ... once. Then write down the answer so that you don't have to ask it again. If you ask the same person the same question more than twice, you're an idiot (in their eyes)." 

I also like to add to this list:

31.  Learn some SQL - Even if it's the most basic of basic stuff - select *, there's no excuse for not being able to query a simple database.

32.  Don't forget your users are stupid - Seems harsh but what seems obvious to a developer will usually not be obvious to the user.  If your software makes them feel stupid then they won't want to use.  Trust me, I know.  

33.  The coolest technology might not be the best technology - Some developers are like cats - dangle a shiny object in front of them - they'll pounce on it like it's the best thing.  Just because you see everything as a nail doesn't mean the latest and greatest of something is the best hammer to use.

34.  Wear sunscreen -  We live in Phoenix, it's important to take care of your skin.Cool

 

 

 



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on March 25, 2008 20:43 by mcollins

While I'm developing, I'm always making changes to code and data, and not necessarily keeping very good or accurate records in the heat of the moment about what I'm changing.  Source code is easy to resolve using modern version control tools, because I can always run a diff to see the changes that I made.  But what do I do about databases?  If I ran some ALTER statements in the database, what happens if I accidentally closed the database session and lost my changes, or if I want to go back and review what I did at the end of an iteration?  What do I do then?

Fortunately, using a trick with triggers in SQL server, I can let SQL Server keep track of the changes that I make in my database.  In my databases, the first thing that I usually create is a table for storing DDL changes to my databases and a trigger that automatically populates the table when DDL statements are executed.  By using the table and trigger, I can go back at any point and review all of the changes that were made to the database.

The table that I usually define is below:

   1: CREATE TABLE dbo.DatabaseModification (
   2:     DatabaseModificationId INT NOT NULL IDENTITY(1,1) CONSTRAINT
   3:         PKNC_DatabaseModification PRIMARY KEY NONCLUSTERED WITH
   4:         FILLFACTOR = 90 ON "default",
   5:     EventType NVARCHAR(256) NOT NULL,
   6:     PostTime DATETIME NOT NULL,
   7:     Spid INT NOT NULL,
   8:     ServerName NVARCHAR(256) NOT NULL,
   9:     LoginName NVARCHAR(256) NOT NULL,
  10:     UserName NVARCHAR(256) NOT NULL,
  11:     DatabaseName NVARCHAR(256) NOT NULL,
  12:     SchemaName NVARCHAR(256) NULL,
  13:     ObjectName NVARCHAR(256) NULL,
  14:     ObjectType NVARCHAR(256) NULL,
  15:     TSqlCommand NVARCHAR(MAX) NOT NULL,
  16:     Note NVARCHAR(MAX) NOT NULL DEFAULT N''
  17: ) ON "default";

 

Most of these fields are populated automatically from information gathered by the trigger.  The Note field was added by me.  This field allows me to annotate the changes in the database while I'm reviewing the database changes.  More and more often, I find that I'm adding this table to my database definitions and including the table in the production databases.  On my applications, I usually also create an administrator user interface for this table because I think that it's handy for a system administrator of an application to be able to look at what changes occurred to a database if something breaks or goes wrong for no apparent reason.  The administrative UI also allows the administrator to edit the contents of the Note field.

Here's the source code for the trigger that populates this table:

   1: CREATE TRIGGER trgDatabaseModificationInsert ON DATABASE FOR
   2:     DDL_DATABASE_LEVEL_EVENTS
   3: AS
   4:     SET NOCOUNT ON;
   5:     
   6:     DECLARE @data AS XML;
   7:     SET @data = EVENTDATA();
   8:     INSERT INTO dbo._zsDatabaseModification (EventType, PostTime, 
   9:         Spid, ServerName, LoginName, UserName, DatabaseName, 
  10:         SchemaName, ObjectName, ObjectType, TSqlCommand) VALUES (
  11:         @data.value('(/EVENT_INSTANCE/EventType)[1]', 
  12:             'NVARCHAR(256)'),
  13:         @data.value('(/EVENT_INSTANCE/PostTime)[1]', 'DATETIME'),
  14:         @data.value('(/EVENT_INSTANCE/SPID)[1]', 'INT'),
  15:         @data.value('(/EVENT_INSTANCE/ServerName)[1]', 
  16:             'NVARCHAR(256)'),
  17:         @data.value('(/EVENT_INSTANCE/LoginName)[1]', 
  18:             'NVARCHAR(256)'),
  19:         @data.value('(/EVENT_INSTANCE/UserName)[1]', 
  20:             'NVARCHAR(256)'),
  21:         @data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 
  22:             'NVARCHAR(256)'),
  23:         @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 
  24:             'NVARCHAR(256)'),
  25:         @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 
  26:             'NVARCHAR(256)'),
  27:         @data.value('(/EVENT_INSTANCE/ObjectType)[1]', 
  28:             'NVARCHAR(256)'),
  29:         @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 
  30:             'NVARCHAR(MAX)'));
  31:     
  32:     SET NOCOUNT OFF;
  33: GO

 

By creating this trigger for DDL_DATABASE_LEVEL_EVENTS, any DDL statements that would modify the database by creating, altering, or deleting database objects will get logged in the DatabaseModification table.

Technorati tags: , , , ,


Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on March 22, 2008 16:39 by mcollins

I've been developing software now for nearly 15 years, and I often repeat the same mistake on every project which leads me down a path to eventual doom and starting over.  This is not just my mistake, I see it happen over and over again from very good developers.  What is that mistake?

My mistake is that there are two pieces to any software development effort.  The first piece is the application.  The application is the piece that implements the features that the end-user or customer wants in the application.  The second piece is the technology.  The technology is what the application uses to implement the features.  My mistake is that I often put too much emphasis on the technology behind the solution instead of on the solution itself.

Non-developers, end-users, and other customer-type people are usually non-technical.  They don't share the same perspective for progress as I do.  I may work for a month and look back and what I have done and be proud of the progress that I have made over that month.  I might have defined and implemented 10 components that all talk to each other using contracts defined by interfaces, and I can run my NUnit tests and show that they can calculate 2 + 2 and tell me in under 1 millisecond that the answer is 4.  I can even run NUnit for my customer and let them see the green bar and share in my rejoicing.  The only problem is that the customer doesn't share in that perspective because they've seen no progress.

At the end of an iteration, what will I have to demonstrate and show?  If the customer's looking for a report with summary data and a nice chart, will I have that for them?  No.  I'll have NUnit with a green bar.

It's this perspective that often leads to friction between developer and client, and is often the first and largest failure that I see software developers make.  It's a fault of ours because we live in the world of technology and there's constant pressure for us to know the latest acronyms such as WF, WCF, AJAX, WPF, Silverlight, HTML, XHTML, and more.  As soon as someone gives us a problem, we start breaking it down by the technologies that will provide us with the best solution.  And this is where we fail.

We think too much about the technologies, while our clients think too much about the final solution.  Does it matter that the solution was a hacked up nightmare?  It might for us, but if it gives the client their summary data and a nice chart, and it doesn't make them take a coffee break and go to lunch while they wait for their report to appear, then it really doesn't matter what technology solved the problem.  It bothers me if the code is sloppy, or if the implementation is not what I wanted to deliver, but my job is to deliver a solution that makes the customer feel like they got their money's worth.  It's not to develop the technology and not deliver them something that they can use.

So when starting a new software project, or trying to fix a broken one, start with the user interface.  Give the customers something tangible that they can touch, manipulate, and play with.  Ultimately, you'll be that much further to delivering them what they want and need than if you through a bunch of technology at the solution and never provided the customer with what they wanted in the first place.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on March 22, 2008 16:25 by mcollins

Tim Heuer, of Microsoft fame, commented on an earlier post of mine this morning and made me think of a lot of things that he probably didn't mean to get me thinking about, but I did regardless.  So here are the results of my thinking.

So when is it ok to build another wheel?  What I mean by that question is when should one rebuild something, versus using something that someone else has already written?  Or to take this another step further, should you spend time building something that someone else has built just for the heck of it, when the original work would have suited your needs?

Usually, I try to take the path of reusing other's work, because ultimately if I am able to do so, it helps me to get closer to my goal.  My main goal usually both on my personal hobby projects and my professional work projects it to build applications that serve a purpose.  My applications are usually built on technology.  The question that I always run into is should I spend a significant amount of time building technology, or should I focus on those things that will help me to actually deliver my application?  The answer that I usually try to strive for is that I want to focus on actually building the application's features, because it's the features that matter to me.  I want to spend as little time as possible focusing on technology, because it delays my ability to complete and utilize a feature, and my main goal is to deliver applications, not invent technology.

So, when it comes down to implementing a feature, if there's something out there that is usable and will help me to achieve my goal, should I use it or reinvent the wheel?  The answer is that I should probably try to use the existing technology so that I can focus on the application.

For example, I came across the SlideShare website back in January and I instantly fell in love with it.  SlideShare is one of the coolest websites on the Internet in my opinion and provides an absolutely fantastic solution to the web community for sharing information.  SlideShare lets you upload your PowerPoint presentations.  Once uploaded, SlideShare will convert your PowerPoint presentations into a Flash application, and you can view your presentation online or embed it in a web page or blog.  Here's an example:

 

This is a fantastic service that SlideShare provides.  However, as a Microsoft developer and aspiring Silverlight developer, it would be super cool if I could put this same functionality into Silverlight and do something such as combine the presentation with additional text, video, audio, etc., all managed through Silverlight, JavaScript, and HTML.

Realistically (because I have researched it), this is something that is possible if I use PowerPoint 2007 and the Open XML APIs to get to the PresentationML and DrawingML markup that make up the slides.  I could spend a lot of time building a Silverlight player and doing all of the hard work to make this presentation control reusable.  Maybe I will do this one day, but right now my primary need is that I want to embed a PowerPoint presentation into a web page, and while SlideShare may only provide me with a feature limited Flash presentation, it's still good enough for what I need at the moment, so maybe I shouldn't worry about reinventing this wheel right now when my main goal is to produce content that I can share with others on the web.

That being said, is it still ok to reinvent the wheel at times, and when is it ok?  Of course it's ok to reinvent the wheel whenever you want.  The main reason why I do it at times is to learn.  I'm a technologist as much as I'm a developer.  I like to learn how things work.  I may create my own ribbon control for my applications to make my applications look like Microsoft Office 2007.  I'm not doing it because I think that I can do it better.  I'm doing it because I want to learn how they do it and understand.  I may not build a ribbon or use it in production code, but the techniques that I gain from tinkering with the technology may help me to apply the technology in whole or in part to other solutions.

Right now on this blog, we're using BlogEngine.NET.  Because I'm documenting how to use the Blogger and MetaWeblog APIs in my earlier posts, does that mean that I'm looking to replace BlogEngine.NET on this website?  No.  I may someday write my own blogging engine, but most importantly by understanding how a tool such as Windows Live Writer or Microsoft Office Word can publish content to a blog, I may find another use for these tools such as being able to publish up to a custom website that I build.  I'd much rather be able to tell my end-users that they can create their content in Microsoft Office Word, which they're usually comfortable working with.  This serves two purposes.  First, my clients can work in a comfortable place such as Word that they know and have skills with.  Second, if my end-users can use Word for content publishing, then I don't have to spend a lot of time building a web-based editing interface (at least right away).  Instead, I can focus my time working on implementing the value generating part of the project, which is the website front-end that content consumers and my client's customers will be using.

In summary, I don't think that it's always right or proper to reinvent the wheel when acceptable options present themselves.  But I'm always a fan of tinkering when it comes to learning and understanding how technology works and learning new ways to apply the technology to your job.  After all, I'm not a fan of not sharing techniques of software development.  There shouldn't be any smoke and mirrors or "magic" behind software development.  The only magic should be that we, as software developers, get to enjoy producing great software that others get to use.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5