Tuesday, July 15, 2008

The difference between projects, namespaces, assemblies, and physical source code files.

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_difference_between_projects_namespaces_assemblies_and.htm]

When creating simple applications, the project, namespace, assembly, and physical source code file usually are all related. For example, if you create a project "ClassLibrary1", it compiles to an assembly "ClassLibrary1.dll", creates a default class in namespace "ClassLibrary1", creates a folder "ClassLibrary1", and places the source code within that folder. Everything is consistent and simple.

 

However, simple is not always enough. These four things can all be independent.

  • Project - The visual studio project that contains all the source code (and other build types like embedded resources), which gets compiled into the assembly. A project can reference any file - including files outside of its folder structure. By opening the project in notepad, you can manually edit the include path to be an external reference: . The file icon will now look like a shortcut.

  • Assembly -  The physical dll that your code gets compiled to. One assembly can have many namespaces.

  • Namespace - The namespace is used to organize your classes. You can change the namespaces to anything you want using the namespace keyword. It does not need to match the assembly or folder structure.

  • Source Code - This does not need to be stored in the same directory as the project. So, you could have several projects all reference the same source code file. For example, you may have one master AssemblyInfo file that stores the main version, and then all your projects reference that file.

So, if you have an aspx page referencing "ClassLibrary1.Class1.DoStuff()", it doesn't care if that class is in Assembly "ClassLibrary1.dll" or "ClassLibrary1Other.dll", as long as it has access to both assemblies and the namespace is the same.

 

This can be useful for deployment, or sharing global files across multiple projects, or just neat-to-know trivia.

Sunday, July 13, 2008

Ideas to encourage your boss to invest in Silverlight

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/ideas_to_encourage_your_boss_to_invest_in_silverlight.htm]

 

Silverlight has a lot of benefits, but as a new technology, it also has problems. As a new technology, it is inevitably riskier as many of the kinks haven't been worked out yet. Managers, who want to avoid unnecessary risk, may shy away from such a technology. However, there are ways to encourage a manager to at least consider Silverlight:

  • Show an actual demo of what Silverlight can do (such as on the gallery). Talk is cheap, but seeing Silverlight in action is powerful.

  • Where feasible, consider developing simple internal tools with Silverlight. Managers almost expect devs to always insist on using the latest technology, regardless of it's business value. But if you believe enough in the tech to invest your own time learning it and applying it to a simple business problem that your department faces - that carries a lot of weight.

  • Emphasize the aspects of Silverlight that would benefit your team - perhaps a rich UI with animating charts, or drag and drop, or rich media, or C# on the client, or cross-browser, etc...

  • If all else fails, consider a little fear-mongering: "Our competitors will be using this". If not Silverlight, at least a Silverlight-competitor like flash.

Some managers were hesitant when JS came out ("it's got cross-browser problems", "not all client support it"), when .Net came out ("J2EE is the established enterprise platform"), when Ajax came out ("it will have security holes"), etc... There's understandably going to be some skepticism with Silverlight too, but that's ok. I personally believe that Silverlight can deliver, and therefore instead of trying to encourage managers to adopt it, managers will be recruiting developers who know it.

 

Wednesday, July 9, 2008

Persisting data in a web app by using frames

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/persisting_data_in_a_web_app_by_using_frames.htm]

A basic problem with developing web applications is that their foundation technology, html, is stateless. That means that you constantly need to jump through hoops in order to pass data from page1 to page2. Of course there are ways to solve this, such as using ASP.Net session state, querystrings, cookies, or persisting to a database. There is another way that may work for simple data if your app is hosted in a frame.

 

Say you have your main page, which is just a frameset. All the navigation occurs within that frameset, such that going from page1 to page2 merely updates the frame's url, it doesn't re-create the host page. This leaves the host page intact, including it's JavaScript state. Therefore, you could have a JavaScript variable persist data between pages.

<html>
  <head>
    <title>My Apptitle>
    <script language="javascript" type="text/javascript">
      var _javaScriptVar = null;
    script>
  head>
  <frameset>
      <frame src="Page1.aspx" id="mainFrame">
  frameset>
html>

You could then reference this variable from your child pages via the DOM:

window.parent._javaScriptVar = "someValue";

This means that page1 could set the value, and page2 could retrieve that value. To the end user, it looks like data has been persisted across pages. You could also expand this using JavaScript hashtables to store name-value pairs of data, and then add wrapper methods for an easy API. This is a surprisingly simple approach, and it has pros and cons:

 

Pro:

  • Very easy to implement for new apps

  • Scalable - as it stores data on the client, instead of on the server (like session state)

  • Can store strongly-typed data. This saves to a JavaScript variable, which can store complex data as opposed to just strings (although you could just use JSON to serialize most complex objects to a string and back)

  • It avoids cookies, which have their own limits and problems.

Con:

  • It messes up your URLs, as the user only sees the URL for the host page, not the child pages. (But this may be a good thing)

  • It is absolutely not secure, as any hacker could modify the JavaScript variables.

  • It does not persist across sessions - it's only good for convenience data on the UI.

Overall, it's a cute trick for certain apps. Although, I'd rather use Silverlight if I could.

Monday, July 7, 2008

Two limits with Silverlight (Beta 2)

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/two_limits_with_silverlight_beta_2.htm]

Silverlight has several fundamental benefits. However, there's always a flip-side, and it has some shortcomings too. There are at least two major limits that I see:

  1. Silverlight requires a separate plug-in. Although Flash also requires a plug-in, Flash has something like 98% market share, and is essentially as available as JavaScript. For Silverlight though, this separate plug-in will make many business sponsors take a second look. Of course, MS knows this and is actively working on it - they'll use the full dominance of MS sites (hotmail, msn, etc...) to prompt your to download Silverlight, they'll make it an automatic update so system admins can easily install it across the enterprise, they'll include it in future products, they'll convince popular sites to use it, and hence encourage all those extra viewers to download it. This separate plug-in is a limit, but not a show-stopper, especially for private or intranet apps.

  2. Silverlight is still a very young technology. After the JS release, and a 2.0 alpha, beta1, and beta2, it still doesn't even have a combo box! However, I'd expect that the Microsoft eco-system will rush to fill in these gaps via open source and the Silverlight community. Silverlight is young, but I'd expect the Microsoft faithful and developer community will make it grow fast.

As a developer, I realize that Silverlight has its problems, and an uphill climb, but I'm optimistic. I think that soon its strengths will outweigh its weaknesses.

Thursday, July 3, 2008

What is the best way to learn coding?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/what_is_the_best_way_to_learn_coding.htm]

I have the opportunity to do a good amount of interviewing, and it lets me see many ways that developers promote themselves:

  • Years of experience

  • Work at a prestigious company

  • Professional awards

  • Certifications

  • Academic degrees (bachelors, masters)

  • Attended training classes

  • Buzzwords

  • Job title ("Extra Super Senior Technical Specialist Level 3++, with Honors")

  • "I've read every tutorial on w3schools"

  • Various activities on their last job

At the end of the day, these are all good, but people who have these still fail simple coding questions. They can talk a good talk, pass multiple choice tests, but struggle when trying to write 10 lines of C# on a whiteboard. Perhaps the #1 indicator of a good developer is that they build their own personal coding projects - from scratch. Not just configure some buzzword package, but actually write, compile, deploy, maintain, and improve their own personal pet project. For example, many of the best developers I know are those who got started by writing their own computer games. I think this actually makes sense for a lot of reasons.

  • Good practice - If you're asked to write code in an interview, what better way to practice than by writing code on your own?

  • Emotional attachment - You have a vested interest in your own pet projects, and a vested interest in their success. Therefore, you'll inevitably be more eager to learn and understand the coding techniques involved, as opposed to some "boring project for work."

  • Small and flexible - A pet project is small, so it's flexible and easy to change - you're not constantly dragging around years of legacy code.

  • Easier to try new things - You're more likely to try new things for your own project, than risk screwing up the company's flagship product.

  • You see the big picture - You see your own project end-to-end, in its full context, as opposed to just a small niche of a much larger product.

  • Lets you focus - A small project, of your own interest, lets you focus on just the specific tech you want, as opposed to writing thousands of lines of redundant or plumbing code for work. It's often a minimalist example of a some interesting technology, because once it gets bloated, it stops being interesting, and the developer stops working on that hobby project, and moves onto another one.

  • Shows motivation - Someone who invests the energy to write their own application, off the clock, is probably motivated to learn new technology and tricks for their work project.

There are tons of fun, pet projects you could build. And with free open-source hosting with places like CodePlex, you can easily share that code with others. If anyone has experienced a better way to learn coding, I'm all ears.

 

Wednesday, July 2, 2008

Why you need to be able to write code on a whiteboard

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_you_need_to_be_able_to_write_code_on_a_whiteboard.htm]

During a software engineering interview, you need to be able to write code on a whiteboard. During too many interviews, at multiple companies, I've seen candidate after candidate struggle to write simple code on the whiteboard. Many of these candidates are decent people, with CS degrees, Master degrees , "years or experience", "senior developer" titles, etc... Yet they cannot write 10 lines of correct code on a whiteboard.

 

For example, such candidates will struggle to answer "given a array of integers, write a method that returns the sum of all the positive numbers." Seriously. This is just a few lines of trivial code - no advanced API, no design patterns, no trivia, no tricks. It's what you'd see in a college CS101, first semester exam:

public static int GetPositiveSum(int[] aInt)
{
  if (aInt == null)
    return 0;

  int intSum = 0;
  foreach (int i in aInt)
  {
    if (i > 0)
      intSum += i;
  }

  return intSum;
}

I've seen experienced, honest, candidates continually miss code of this simplicity.  They'll have logic, syntax, or style problems:

  • Logic - They'll add the numbers wrong, such as overwriting sum (intSum = i), or adding it exponentially (i += i), or completely ignore any validation (what if an input parameter of a public method is null?) It's one thing not to get bogged down in tedious plumbing, but a candidate should be prepared to call out if something could crash their code.

  • Syntax - A significant chunk of developers just dismiss syntax, emphasizing that they know the concepts instead. Good recruiters don't care about trivia, like if you miss a semi-colon at the end. But I've seen people have the wrong method signature, declare a variable wrong, have the wrong for-loop syntax, or reference an array wrong. A mistype is okay, but when you try to drill down on concepts ("Does the variable intSum need to first be assigned before being used?", "Will your loop execute the correct number of times?"), and they shrug it off, that's not good.

  • Style - Style is subjective, but important none-the-less. A good recruiter doesn't care if you indent with two spaces or four spaces. But there are other "style choices" that really do matter. I've seen developers declare their variable out of scope, such as using an extra static member instead of keeping it encapsulated as an instance field. I've also seen many devs just dismiss validation by wrapping the method in a try-catch. Or they'll make a method instance when it could be static instead. It's okay to have personal coding preferences, but these kind of "style" things actually affect the functionality of the code. A candidate should be prepared to explain why these made certain "style" choices.

Obviously, recruiters know that the candidate can write code, and could stumble through 10 lines of C#. But the idea is that if a candidate struggles to write trivial code, without the aid of Visual Studio's intellisense, compiler, and debugger, then they don't really get it. In other words, if a candidate uses VS as a crutch for simple code, then they're probably just "coding by coincidence" as opposed to proactively thinking through the code. And while you can "code by coincidence" for easy problems, on small, standard, applications, it will result in endless bugs on larger, complex apps. For example, if a candidate doesn't realize that they need to check for a null input parameter on simple code (even when prompted), how can they be expected to validate complex and critical code?

 

Some interviewees seem to dismiss these coding questions as "beneath them". The problem is that you must judge the unknown by the known. If a recruiter observes the candidate mess up simple code (that the recruiter can see), they'll be less likely impressed by fancy-sounding projects that they [the recruiter] cannot see. In other words, if for whatever reason the candidate cannot conceptually work through simple code, most recruiters won't even pay attention to all that allegedly complex code that the developer wrote elsewhere.

 

As a candidate, this coding on the whiteboard is the chance to shine. This is not the time to say things like "I guess this is how you do it", or "I'm trying to remember back in my college days". Rather, this is where the candidate can show that they know C# so well such that they can write it straight - without any crutch - and then explain it, and then adapt it on the fly. Now that's a great way to get off to a good start in an interview.

 

 

FYI, here are some of the unit tests that I'd run the above code through:

Assert.AreEqual(0, GetPositiveSum(null));

Assert.AreEqual(0, GetPositiveSum(new int[] { 0 }));
Assert.AreEqual(0, GetPositiveSum(new int[] { -1, -4, -4 }));
Assert.AreEqual(0, GetPositiveSum(new int[] { 0, -4 }));
Assert.AreEqual(0, GetPositiveSum(new int[] { Int32.MinValue }));

Assert.AreEqual(4, GetPositiveSum(new int[] { 4 }));
Assert.AreEqual(10, GetPositiveSum(new int[] { 1,2,3,4 }));
Assert.AreEqual(4, GetPositiveSum(new int[] { -4, 4 }));
Assert.AreEqual(Int32.MaxValue, GetPositiveSum(new int[] { Int32.MaxValue }));
Assert.AreEqual(3, GetPositiveSum(new int[] { 0, 1, 2, -3 }));

.

 

Tuesday, July 1, 2008

Why you shouldn't just wrap simple code in a try-catch

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_you_shouldnt_just_wrap_simple_code_in_a_trycatch.htm]

Structured programming languages, like C#, provide a try-catch ability to wrap an entire block of code, and catch if anything goes wrong. This can massively simplify error checking, especially when calling external components. However, like any good thing, it can also be abused. During interviews, or rushing out code, many developers resort to using try-catch as a quick way of doing error checking, but there's a catch (excuse the pun). For example, consider this trivial method to sum up an array of integers:

 

    public static int GetSum(int[] aInt)
    {
      int intSum = 0;
      foreach (int i in aInt)
      {
          intSum += i;
      }
      return intSum;
    }

 

You can crash this code, such as by passing in null for the int array.  To blindly wrap a simple method with try catch, just to catch normal logic errors like null variables or indexOutOfRange, has problems.

  • For performance, Try-catch is enormously expensive compared to an if-then check. It could be hundreds of times slower. So it's bad design to use a try-catch for something trivial when an in-then will do just file, like checking if a variable is null.

  • What will you do in the catch statement? Some devs may say "I'll log my exception info here" - but what info is that... that the developer didn't bother to do basic error checking?

  • It makes the usability worse. Perhaps instead of re-throwing an exception, or logging and going to the global error page, the method could have used an if-then to return a sentinel value instead. For example, perhaps a string manipulation method could just return the original value (or null) if the input parameters were invalid.

  • It loses context. Say your code catches a null exception - that thrown exception doesn't tell you what variable was null. You've lost context and information with which to fix the code. Using an in-then would have given you full access to all the local variables and their context.

  • It makes all exceptions equal - a null or indexOutOfRange exception (things that are easy to catch with if-thens) are put on the same level as a critical outOfMemory error - i.e. both trigger the catch block. This in turn can distract the maintenance team, who gets swamped with tons of exceptions, most of them preventable.

  • Perhaps worst of all, it implies that the developer isn't thinking about how their method can fail. Rather than understanding the code and what it does, they just wrap it all in a try-catch, and move on. This means they could have not coded for valid use cases.

Try-catch has obvious benefits, but it has limitations and consequences too. There are times when it's much more beneficial to explicitly catch the error conditions with an if-then instead.