Wednesday, July 11, 2007

Practical Software Factories in .NET

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

I'm a big fan of automation (especially via MSBuild and CodeSmith), so I'm very interested in the Software Factory community. I recently finished Practical Software Factories in .NET by Gunther Lenz Christoph Wienands. As I understood it, they emphasized four main parts for a software factory:

  1. Product Line Development - emphasis on a specific type of software (web apps vs. 3D-shooters vs. winForms)
  2. Reusable assets - class libraries, controls,
  3. Guidance in Context - this could be as simple as instructions in the comments of generated code
  4. Model-driven development (i.e. Domain Specific Languages) - working at a high level of abstraction.

A lot of this boils down to standardization, automation, and reuse - things already covered by classic books (like the Pragmatic Programmers). However, the software factory methodology provides a structured way to achieve those things.

I also found this book interesting because it discussed concepts at a much higher, and more practical level. for example, there are plenty of "syntax" books out there, like How to Program Technology X. There are also lots of conceptual books that address the theory and problems of software engineering, like Code Complete, The Pragmatic Programmers, Joel on Software, or The Mythical Man-Month. These transcend individual, and are therefore still relevant as new technologies come out.

Practical Software Factories is different because it both address concepts, yet refers to the current technologies, websites, articles, and open-source projects to achieve those concepts. So even a year or two from now, when the current crop of  tools and articles are replaced, its concepts will still be relevant, and likely implement-able with a new wave of tools.


Living in Chicago and interested in a great company? Check out the careers at Paylocity.

Wednesday, June 6, 2007

Using Generics for dynamic return type and validation.

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

Generics are a .Net 2.0 feature that essentially let you abstract out type. You can learn a lot about generics on MSDN.

One problem that generics can solve is how to have a method dynamically return a given type. For example, in the snippet below, the method GetData returns different types depending on what you pass in - either a double or an Int32. This is useful for creating a generalized method to parse out (and potentially validate) data. Note that the consumer of the GetData method need not deal with conversion - it receives a strongly typed value.

While this is just a trivial snippet, it's a nice demo of one of the features of generics.

    [TestMethod]
    public void DemoGenerics()
    {
      int i = GetData("123");
      double d = GetData("456");

      Assert.AreEqual(Convert.ToInt32(123), i);
      Assert.AreEqual(Convert.ToDouble(456), d);

    }

    public static T GetData(string strData)
    {
      string strType = typeof(T).Name;

      switch (strType)
      {
        case "Int32":
          return (T)(object)Convert.ToInt32(strData);
        case "Double":
          return (T)(object)Convert.ToDouble(strData);
        default:
          throw new Exception("Type not supported");
      }
    }

 


Living in Chicago and interested in a great company? Check out the careers at Paylocity.

Thursday, May 31, 2007

How to tune a SQL script

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

Performance is critical, and slow SQL procs are often a huge performance bottleneck. The problem is how to measure it. Microsoft provides SQL Profiler to help with that.

While I'm certainly no DBA, here's a basic tutorial on how to tune a SQL script (check here for more on SQL profiler).

1. Get a database with production-sized data.

Because performance can very exponentially (i.e. there may be twice as much data, but it goes twenty times slower), you absolutely need to test with production-sized data, else all your measurements could be off.

2. Be able to run the SQL script in an isolated, deterministic environment

We don't want to chase ghosts, so make sure you have a deterministic environment: (A) no one else is changing the script-under-test, (B) you can call the script with a single SQL command (like exec for a SP, or select for a function), (B) you can call the script repeatedly and get the same functional result every time. Once the script works, we can make it work fast.

3. Open up SQL Profiler for a tuning template.

SQL profiler lets you measure how fast each SQL command took. This is invaluable if you have a complicated script with many sub-commands. It's almost like stepping through the debugger where you can evaluate line-by-line.

  1. Open up SQL Profiler (either from SQL Studio > Tools > SQL Server Profiler, or from the Start > Programs menu).
  2. In SQL Profiler, go to File > New Trace, and connect as the SA user.
  3. In the "Use the template", specify "Tuning"
  4. Open Profiler
  5. Profiler starts recording every command being sent to the database server. To filter by the specific SPID that you're running your SP from, run the SP_WHO command in your SQL Studio window to get the SPID, and then in SQL profiler:
    1. Pause the SQL Profiler trace
    2. Goto File > Properties
    3. A new window opens up, go to the "Events Selection" tab
    4. Select SPID, and in the filter on the right enter the value into the "Equals" treeview option.
    5. Filter SPID

 

4. Run your SQL statements and check the Profiler

Simply run your SQL statements in SQL studio, and check the results in SQL profiler.

The tuning template in profiler will record every command and sub-command being run. It will show the total duration (in milliseconds) for each line, and the full SQL text of what was run. This allows you to identify the bottlenecks, and tune those by changing the SQL code to something more optimal.

Trace

5. Compare the output to ensure same functionality

If you don't have an exhaustive suite of database tests, you can still help ensure that your proc is functionally equivalent by comparing the original SQL output (before tuning) to the new SQL output (after tuning). For example, you could save the output resultset as a file and then use a file-diff tool like Beyond Compare to ensure they're identical.

Summary

Again, books could be written on how to SQL tune. This is just a brief high-level tutorial to get you started.

 


Living in Chicago and interested in a great company? Check out the careers at Paylocity.

Wednesday, May 30, 2007

Development Trivia

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

Real-world development has so many miscellaneous facts and trivia, so I'm going to experiment writing a "Friday Trivia" blog post. The intent is to discuss trivia that arose during the week.

Specify the default editor for a file

In windows explorer, right click a file, select "open with" > "choose program", and then check the checkbox that says "Always use the selected program to open this kind of file". You can then automatically open the file (in the designated editor) just by running System.Diagnostics.Process.Start(strFullFileName).

Selecting Comments with XPath

XPath is a powerful way to select nodes from an XML document. While XPath commonly selects normal nodes, you can also use it to select elements. For example, you may want to select a comment if you're inserting a node into a document, and want the comment to be a placeHolder for where you append that node.

      XmlDocument xDoc = new XmlDocument();
      xDoc.LoadXml(@"
       
            Additional Notes
           
            Text notes
       

        "
);

      XmlNode n = xDoc.SelectSingleNode("/employees/comment()");

 

MSBuild - Command line properties that contain CSV strings

In MSBuild, you can specify properties via a or with the /p: switch in the command line. These two are supposed to be identical, but they're not. You can specify a CSV string in a PropertyGroup just fine, but you can't in the command line switch because it interprets commas as a property delimiter (just like semi-colons). A work around is to use another character (like a hyphen '-'), or have the MSBuild script import the PropertyGroup from a separate file and write the CSV string to that file. Perhaps there's also a way to escape the comma (maybe with a carrot '^')


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.

Tuesday, May 22, 2007

12 more things that will really help your team

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

Every enterprise software department should have some basic processes and standards. Joel Spolsky has a great list here. There are some additional things that will really help your team:

  1. A team vision - What really is your team striving for?
  2. The willingness to pay for talent - Because a good developer is much more productive than an average developer, it is only cost-effective to pay for good talent. A CXO whose business model is to get cheap developers will probably be as successful as a cook who tries to save money by buying moldy ingredients. On a related note, a department needs to retain it's top talent. Managers need to ask themselves - why would our top developers stay here?
  3. Thought Leadership - By contributing to the technical community, via articles, presentations, blogs, open-source, etc..., a department (1) shows that they're doing innovative work, (2) shows that they have the intellectual muscle to break new ground, and (3) creates a sense of company pride. This helps market the company, making it more attractive to top talent.
  4. Innovative Process - Are your processes better than they were a year ago, or did someone set things up and now you're done "wasting time" on process? Good process, like continuous builds, automation, and utilities will save your team an immeasurable amount of time. A department that refuses to invest in its process is doomed.
  5. A way to enforce standardization - such as code generation, code reviews, resuable components, and static code analysis.
  6. Tools beyond just Visual Studio, like a file comparison tool (like Beyond Compare), and a non-VSS source control system (we use Subversion). Of course, there are tons of tools out there:
  7. Ways to track progress - How do you know how much more development time a feature needs? Ideally your department has some sort of time-tracking system, with categories for how time is spent. This lets you see how many hours a feature initially took, including the time spent in design, and fixing bugs. If management wants a knee-jerk mentality that always delays doing any good process or innovation because "we don't have the time", a tracking system will give you the hard data to make the business case that you save more time by doing the feature correctly first. I.e. If you can show management that developers spend 50% of their time fixing bugs (both a  high-risk and hard-to-estimate activity), then you can at least explain, in business terms, why it's best to invest in good architecture and process. (If management still doesn't see this, then your department will have a bigger problem).
  8. Automated Deployment - Ultimately every step in deployment should be able to be automated. Doing manual deployment is just too risky and time consuming. It's not just your IT department that needs this - your QA needs automated deployment for performance or functional testing (because QA's environment should mimic Production). Ideally your continuous build will create an install package that your deployment framework can then just install from the command line. Maybe you need to serialize your deployment strategy to an XML file, and pass this in via the command line, maybe you do some manual steps once (like copying your config files to their appropriate locations), but ultimately you don't want to be wasting time manually doing a mission-critical step that could be automated. If a department has some special exception case that they need to do a manual deployment - that's their choice - but at least they'll also have the choice of doing it automatically too.
  9. Hiring of college grads -  If your company is growing and investing in its future, getting smart college grads is a good investment. Most of the brand name companies, like Microsoft or the big consulting companies, have a place for college grads because they know that in a few short years, the smart ones will already be delivering impact. It can also be much easier to home-grow a star than try to poach an established senior star from another company.
  10. Have knowledge collaboration - Wikis (like FlexWiki or SharePoint) are just too valuable to pass up on. If your department doesn't have a wiki "because we can't afford it", then get the open-source FlexWiki. It's free and runs on a Windows XP box. You can have it set up in less than an hour.
  11. Have mentors - Good companies invest in their employees, and one of the best ways for a software company to do that is by having senior devs mentor junior devs. You don't need a suffocating formal process, even just having a senior dev consistently review someone's code, encourage them to invest in certain technologies, or just meet them for a casual lunch, is a good start.
  12. Have career goals - do you know where you, as a developer, want to be in 5 years? Ideally your department has a clearly defined career path. "Better at the current technologies" isn't really specific enough. At Deloitte and CSC (my previous companies), every consultant needed to list several short and long term goals for their yearly review. This forced the consultant to think  about their future, and gave the consultant something to shoot for.

In hindsight, it's east to say "we should have XYZ", but most departments lack these things. In my experience, it's a combo of: (1) an inexperienced department that doesn't know what they're looking for (I've certainly been there when I was younger), (2) lack of budget to build this infrastructure, or (3) lack of motivation for developers to build this infrastructure. If your department is missing a lot of things on this list, and you think it would help your specific case, you can try gradually chipping away at them one-by-one.

Once you start doing a good process, you wonder how you ever could have have lived without it.


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.

Monday, May 21, 2007

How to encourage standardization

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

You cannot control people, you can merely encourage an option to be in their best interests.

With respect to code, we all want standard, consistent code - but the question is how? Especially if you have a group of individuals who all are used to doing things their own way. There are some ways to encourage standardization:

  1. Code Reviews (XP uses the ultimate code-review: peer programming). This will encourage people to share ideas and "melt" their concepts together, ideally picking the best of everyone's world.
  2. Refactoring and Reusable components. If you eliminate the possibility of bad variation, your encourage good standardization. For example, there are many different ways to format a DateTime. But if you have a strongly-typed DateTime control that handles the formatting and validation for you, and developers simply drag and drop that control onto their page, you've got a win-win: (1) it's faster for the dev to create, and (2) all your DateTimes are now standardized.
  3. Static Code Analysis (like FxCop, built into VS 2005). This is like compiler warnings on steroids. This gives you proactive warnings about your code, like naming standards and style. It's great if you're starting to code from scratch, but could give excessive noise if used on legacy code. It's also hard to enforce - i.e. FxCop gives you back a 1000 warnings, and most developers then just dismiss it as noise.
  4. Code Generated templates based on model-driven languages - Using a tool like CodeSmith, you can take an XML file and generate a bunch of ascii text - like C# and HTML code. This shrinks the gap between what it takes to describe a feature (a minimalist XML file), and what it takes to implement the feature (the generated C# and HTML).

A lot of this ties into software factories. I'm currently reading Practical Software Factories in .NET by Gunther Lenz and Christoph Wienands - it provides a lot more insight about this.

Sunday, May 20, 2007

Making a transparent Gif with the free Paint.Net

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

Sometimes a developer will need to make a transparent GIF, such as for a web page. This should be trivial - you essentially want to say "make every pixel that is color X be transparent", but most standard development tools (VS, Paint, etc...) don't let you do this. While there are lots of expensive graphics programs out there, most developers don't have these.

An easy way to make a transparent gif is using the free Paint.Net (written entirely in .Net).

  1. Download Paint.Net. It's a pretty good, free, graphics editing tool.
  2. Open up your image. Save it as a gif.
  3. In the Tool section, use the "Magic Wand" feature.
  4. Set it's tolerance to '0%'
  5. Drag it over the section you want to make transparent. The magic wand catches an entire region of adjacent, same-color-range, pixels
  6. Once the region is selected, then hit the delete key. [Updated 12/11/2007]

I find this convenient for simple web imaging needs. Also, Paint.Net has a ton of other features, like gradients, blends, and special effects.

 


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.