Wednesday, November 29, 2006

Ildasm: Viewing attributes

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

Yesterday I mentioned ILdasm to view the meta data on an assembly. One of the benefits of .Net is that it requires meta data for all assemblies. You can even create your own strongly-typed meta data via attributes. For example, both NUnit and MSTest use attributes to indicate that a certain method is a unit test. Because all the meta data is public, these external programs can use reflection to loop through all the methods in an assembly, and check which methods have which attributes.

These attributes show up in the IL. If you use Ildasm to view a method, you'll see which attributes it has. The IL snippet below has both the [TestMethod] attribute used by MSTest, and my own custom [Duration] attribute.

.method public hidebysig instance void  Duration_String_1() cil managed
{
  .custom instance void [Microsoft.VisualStudio.QualityTools.UnitTestFramework]Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute::.ctor() = ( 01 00 00 00 )
  .custom instance void TestDemo.Duration.DurationAttribute::.ctor(float64) = ( 01 00 7B 14 AE 47 E1 7A 84 3F 00 00 )             // ..{..G.z.?..
  // Code size       18 (0x12)
  .maxstack  2
  .locals init ([0] string s)
...
  IL_0011:  ret
} // end of method Strings::Duration_String_1

Of course, you'd probably never use Ildasm to read the attributes, but it's good to know that everything is consistent - i.e. meta data is public for any .Net assembly - it's not cryptic information only for debug more or something (like a *.pdb). So it makes sense that external programs like MSTest and NUnit can read these attributes.

Tuesday, November 28, 2006

Measuring the CLR, using ILdasm

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

I've been looking more at the .Net CLR, i.e. how .Net really works under the hood. Because most of my work and hobbies are application development, it's easy to take the CLR for granted.

I've been reading Don Box's (with Chris Sells) Essential .Net Volume 1: The Common Language Runtime. I'll try to blog more about each chapter as I read it. Obviously given the popularity of both authors, it's a good book. Even though it's for .Net 1.0, it's still very practical.

It makes it much easier to understand something if you can observe and measure a cause and effect. Many devs I see don't try to understand the CLR because they can't measure much about it - such as how much memory some code takes, how fast the code runs, what happens when it gets compiled, etc... For example, many devs use try-catch to do business logic checks, and don't worry about performance because it "works fast enough on my machine."

I'm no CLR guru (you can see the official Microsoft CLR bloggers here), but I'll be blogging my adventure digging deeper into the CLR.

To kick it off, I started with Ildasm (view MSDN tutorial here). As every .Net book points out, .Net languages (like C# and VB.Net) get compiled into MSIL - Microsoft Intermediate Language - or just IL for short. This allows .Net to be language independent, because no matter what language you code in, it gets compiled to the same IL. Ildasm lets you see that compiled IL.

First, you can see the IL Specification here.

You can run Ildasm by opening the VS command prompt and just typing "ildasm". If you go to File > Open, you can browse for an assembly, load it, and then view its IL and meta information.

Here are some immediate benefits of what you can see with IL:

  1. Whether this is a debug or release assembly - the Debug version will have an extra line:
        // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute
  2. The meta data for the assembly (like company name)
  3. What other assemblies this one references.
  4. The actual IL. So, for example, you could see the number of boxing and unboxing operations by checking for the box and unbox IL commands.
  5. All the types and classes in the assembly.k

A super-version of IL, which can take an assembly and convert from the IL back to a .Net language is Lutz Roeder's Reflector. This is very useful for reverse engineering an assembly - even Microsoft's own system assemblies.

I'll blog more about this in my upcoming posts.

Monday, November 27, 2006

Logical puzzles

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

This is a cool website: http://www.techinterview.org/

It lists a bunch of logic puzzles that you'd likely see in a tech interview. Nice way to start the morning.

Sunday, November 19, 2006

Adding an Event to a User Control (Code Sample)

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

I had talked about how to trigger an event from a UserControl.

This ability has many benefits, such as with refactoring. For example, suppose a UserControl is hosted on many different pages, and each page requires that the control have slightly different validation that incorporates values from the host page. One way to do this is to have the UserControl call a validation method on the host page.

Here's a code snippet you can download that shows how to have a UC call a method on its parent. The idea is to add an event member to the control, and hook it up with a delegate. (I had initially seen this technique from an article on MSDN several years ago).

This specific example has four files:

  • A UserControl - RecordNav.ascx and RecordNav.ascx.cs
  • A host page - HostRecordNav.aspx and HostRecordNav.aspx.cs

The UserControl contains an event "UpdateDate" and the host page adds a method to handle the event: RecordNav1_UpdateData.

    RecordNav1.UpdateData += new AspxDemo_Events_RecorNav.UpdateDataEventHandler(RecordNav1_UpdateData);

Wednesday, November 15, 2006

CNUG Presentation followup - MSBuild with source code samples

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

Yesterday's presentation at the Chicago .Net Users Group went well. Paylocity sponsored it with a presentation on MSBuild: A Process Automation Language.

You can download the presentation and code samples here.

Here's the abstract:

.Net 2.0 introduces MSBuild – Microsoft’s new build engine with a process-oriented scripting language. While MSBuild is marketed for compilation and build processes, it is really a full-fledged automation language. It includes structured control flow, variables, refactorability, error handling, logging, and powerful extensibility. You can easily integrate MSBuild into your own enterprise processes and start adding value right away.

Tuesday, November 14, 2006

Multi-tasking with background processes

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

A miscellaneous thought for the day: Given enough time, what (non-computer) background processes do you run in your everyday life? Letting the dishes soak to get out a tough stain, or letting clothes air-dry?

If you have the time, these processes are very cheap yet effective. People who don't have the time pay for extra products to make these processes go faster (a powerful dishwasher, chemical cleaning products, or clothes dryer). It's the old cliche - time is money. Software development is the same way. Being able to just kick off a background process that does work for you can be a great way to increase productivity. It's like being able to do two things at once, such as integrating your code (continuous build on a build server) and doing local development, or running a local pre-checkin script to verify for unit test errors and reading a design doc.

It gets especially cool if you have access to other machines (or virtual machines), and you can kick off more than two things at once - like having a database integration test run on Machine X, performance tests run on Machine Y, Static Code Analysis / Unit Test coverage run on Machine Z, all while catching up on email.

All this really requires is the desire to multi-task, and the hardware to do it. Given that a computer is much cheaper than a developer, if one is multi-tasking properly, it could be well worth the investment

Monday, November 13, 2006

Presenting at Chicago .Net Users Group on MSBuild

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

This Wednesday (Nov 15) I'll be presenting at the Chicago .Net User's Group on MSBuild: A Process Automation Language. Pizza starts at 6:30pm, the presentation at 7:00.

.Net 2.0 introduces MSBuild – Microsoft’s new build engine with a process-oriented scripting language. While MSBuild is marketed for compilation and build processes, it is really a full-fledged automation language. It includes structured control flow, variables, refactorability, error handling, logging, and powerful extensibility. You can easily integrate MSBuild into your own enterprise processes and start adding value right away.

It should be a good time.

Sunday, November 12, 2006

Does .Net 2.0 make developers "dumber"?

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

 

When .Net 2.0 came out, it had a slew of powerful new features that made many things easier. Some people have asked: "Does .Net 2.0 make us all dumber?" The thinking is that .Net 2.0's new power spoils us, much like calculators spoil many of today's kids from no longer being able to do basic arithmetic.

My answer is no - .Net 2.0 does not make us all dumber, for at least three reasons:

  1. By simplifying certain tasks, .Net 2.0 frees up mental resources so that we can focus on other, more interesting things instead. This doesn't make a dev dumber, it just lets them focus elsewhere instead.
  2. .Net 2.0 doesn't just take existing things and make them easier, it also breaks new ground such that you can do more with the same effort. For example - ASP.Net 2.0 introduces web callbacks - an alternative to postbacks. It's a standard tradeoff: callbacks are more powerful, but require more effort. This actually lets a dev be smarter, by making it practical for them to deal with more complex techniques.
  3. Some things an average dev just couldn't do before - like web parts. Having this new power doesn't make the dev dumber, it just means that the same intellectual effort can go farther now.

There will always be a spectrum of smart, average, and below-average developers. As the technology continually grows, I think the trend isn't that the whole spectrum is getting dumber, but rather that it's getting more polarized. For example, .Net drastically lowered the entry-level for web programming (so less-smart people could start becoming web developers), but it also let you do more (so power users could do more).

Friday, November 10, 2006

Ego Star vs. Humble Average

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

There is an interesting conflict between skill vs. humility:

  1. Software teams requires smart people
  2. Smart people tend to be more egotistical (because they think they're smarter than everyone else)
  3. Egotistical people can hurt software teams because they ruin the chemistry and are no fun to work with.

So, the problem is that a smart person helps the team, but smart people usually have egos, which hurt the team. It prompts the question, would you rather have a coworker that is an egotistical star, or a humble average? (Of course everyone wants the best of both worlds, but life affords very few of those).

I see pros and cons to all the options on the spectrum. If you're doing a highly-complex feature, you may need the skills of the egotistical star, and may just need to tolerate the ego that goes along with it. If you're doing more commodity-type work, the humble average guy could be sufficient.

Personally, I'd like a balance, but find teamwork to trump ego. Because in enterprise architecture, you're always on teams with other people, and getting along with those people makes a world of difference. I'd rather be 10% late, and appreciate the team, then 10% early and hate the job.

I also find it's easier to learn from humbler people because they're more willing to share ideas, don't take criticism personally, and put the good of the project ahead of their personal ambitions.

Questions that I'd ask when trying to pick a person for a team:

  • Is this position on a team - will they be working with other people?
  • Are the skills replaceable? A developer's whose skills are easily replaceable doesn't have the right to be egotistical.
  • Can you constrain/redirect their ego to something constructive (such as convert it into pride of ownership for difficult components, which helps the team).

Thursday, November 9, 2006

MSBuild: Read and Write from a File to a Variable

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

MSBuild lets you easily read and write values from files into variables. While you could write your own custom tasks to do this, MSBuild provides out-of-the-box functionality with the ReadLinesFromFile and WriteLinesToFile tasks.

You can read from a file into a variable:

    <ReadLinesFromFile File="Version.txt">
      <Output TaskParameter="Lines"
        PropertyName="Prop1" />
    ReadLinesFromFile
>

This will store the contents of the file "Version.txt" in a dynamically created property "Prop1".

You can also write to files:

      <WriteLinesToFile File="myFile.txt" Lines="This is a test value." Overwrite="false" />
      <WriteLinesToFile File="myFile.txt" Lines="A second line." Overwrite="false"
/>

Wednesday, November 8, 2006

Interview Tips

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

I've had the privilege of giving a lot of interviews at three different companies. The ideal is to find a win-win combo: a good candidate that fits within a good team. Here are some random tips to help the candidate and interviewer.

Candidate

  • You know that you are going to be asked certain questions, so be ready for them. You should have prepared, ready answers for questions like "What do you know about our company?", "What's the most difficult task you've done?", or "Why do you want to work here?"
  • Be prepared to actually write code on a whiteboard. You wouldn't believe how many developers cannot write the 5 lines of code for something as simple as the textbook problem "return X factorial". Sure, they've coded before (or so their resume says), and they could probably solve it with Visual Studio, but still. The thinking is that if on a scale of 1 to 10, writing "return X factorial" is a 1, if the candidate can't even do that on a whiteboard without an IDE, then it's pointless to go farther.
  • You want to show the interviewer that you can think, not just regurgitate facts. If they ask you a simple coding question, check if it's appropriate to "think out loud" so that they don't just see some final answer, but rather your intellectual process. This is also great for getting "partial credit" if your answer is wrong.
  • Have a realistic expectation of your abilities. For example, I constantly see devs who call themselves "Senior .Net Lead Architect" for a 1 person project they did their first month out of school. It's especially scary if they can't even tell you what a design pattern is.
  • Build up your technical confidence.
  • Everyone has "project experience", and eventually they all blur together. Be prepared to emphasize your extracurricular activities.
  • Know some of the industry terms and buzzwords.

Interviewer

  • Have standard questions you can ask everyone, which lets you compare candidates against the same benchmark.
  • Ask both technical questions, and behavioral questions.
  • Show respect to the candidate: (1) It's only professional, (2) They may very well be a lot smarter and more experienced than you, (3) You may need them more than they need you - i.e. a smart candidate will have multiple job offers, why should they work at your company?
  • Focus on concepts, not trivia. Any professional team recognizes that you can learn new concepts (especially with the technology constantly changing). Software Engineering is too deep to waste your time memorizing trivia from reference manuals. Who cares if you can list all 19 constructor overloads of Foo.
  • Avoid the ego at all costs. Do not assume that the candidate is some helpless hack who is at your mercy for a job. I've seen people get an ego rush from having the opportunity to interview - they research some obscure trivia, and then hammer a senior candidate on it, and take a sense of pleasure in trying to "push around" someone who they really have no business to be in the same room with.
  • Could you pass your own interview?

Tuesday, November 7, 2006

Foreach loop in MSBuild

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

Yesterday we mentioned how MSBuild can handle conditional logic. It can also handle looping using the concept of "batching" and ItemGroups.

<Project    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">        <ItemGroup>        <ExampColl Include="Item">            <Number>123Number>        ExampColl>        <ExampColl Include="Item">            <Number>456Number>        ExampColl>        <ExampColl Include="Item">            <Number>789Number>        ExampColl>    ItemGroup>    <Target Name="ShowMessage">        <Message Text = "Number: %(ExampColl.Number)"/>    Target>Project>

The first step is to make an ItemGroup - which is simply a group of items that you can potentially loop through. Each ItemGroup needs the required "Include" attribute. For a basic example, lets just set this to "Item". The power comes in that you can add your own custom attributes to the ItemGroup, such as "Number".

You can then reference (and loop through) the ItemGroup using "%(.)", such as "%(ExampleCol1.Number)". When run, the above snippet produces the following output. Notice the Message task being called three times - once for each item in the ItemGroup.

Target ShowMessage:
    Number: 123
    Number: 456
    Number: 789


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.01

There's a lot more that you can do with Task Batching, but this is a helpful start. You can replace the Message task with any task you want, and use the '%' character in any attribute of that task. It's a lot cleaner than the DOS for loop.

Monday, November 6, 2006

Conditional Logic (If-Then-Else) in MSBuild

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

MSBuild provides the ability to do an if-then-else control structure, using the Condition attribute, which is available to every task. Simply put, the task only runs if the given condition is true.

An If-Then-Else means "if the condition is true, run the first statement, else run the second statement". This is logically equivalent to: If 'X' is true, run S1; If 'X' is false, then run S2. We can use the task's Condition attribute, with the ! ('Not') Operator to achieve this. For example, in the snippet below, if the variable "RunTask" is true, then the first line is run, else the second line is run.

    <Message Condition="$(RunTask)" Text="Do X" />
    <Message Condition="!$(RunTask)" Text="Do not do X" />

You can see a list of allowed conditional expressions in the MSBuild reference. It includes operators ( <, >, <=, >=, ==, !=, !, And, Or), parenthesis, and even an "Exists" function to see if a file exists.

Friday, November 3, 2006

The Benefits of Reinventing the Wheel

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

When someone else already makes a good, working tool, you may not want to reinvent the wheel and build a similar thing yourself. Of course we want to reuse code and not waste time repeating someone else's work. However, as an extracurricular activity, there can be benefits to creating your own version of an interesting tool:

  • Great learning opportunity - You'll understand something better when you build it yourself. You can then also compare your solution with the industry standard, and check for general trends to possibly improve your programming (i.e. "I did it this way, but they did it that way... ah... that's why they did it that way.")
  • A sense of personal accomplishment - you may a fun tool. That someone else already made a similar tool doesn't diminish your own adventure.
  • An appreciation for the tool when you see how hard it was to write.
  • The possibility that you can write it better.
  • You can customize it to your unique needs.
  • If the tool isn't free, you can now have your own copy that you don't need to worry about licensing for.
  • It's fun to write cool tools - even if someone else already has. Especially when you're a younger developer, you need to start somewhere - you can't always write flashy new things that no one has seen before.

Thursday, November 2, 2006

Taking notes with Microsoft OneNote

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

In our profession, there is a constant need to take quick notes. Ideally, there'd by a way that is (1) quick to load, (2) flexible, (3) searchable, (4) different information formats (pictures, outlines, tables, paragraphs), and (5) low maintenance. I've played around with several techniques:

  • Using Notepad files on my desktop
    • PRO: very quick to load and make edits
    • CON: very little formatting (outlines & tables), no image support, not scalable
  • MS Word
    • PRO: Lots of formatting ability
    • CON: To bulky, html is bad
  • FrontPage
    • PRO: Lightweight, friendly HTML that can easily be used on the web, easy hyperlink to other pages
    • CON: Each resource (like an image) is its own external object - not embedded as a single file.
  • Visio
    • PRO: Decent for formal images
    • CON: Designed mainly for diagrams and modeling, not for note taking
  • Wikis
    • PRO: Optimized for easy entry and search-ability
    • CON: Entered with plain-text formatting limits your options
  • Custom Tools - I've looked at SourceForge's Freemind, and tried to build some things myself

Also, all of these are funneled to a specific purpose designed to make formal documents, not informal note taking. Enter Microsoft OneNote - a desktop app designed explicty for note taking. Some benefits:

  • Quick start up (it can run in the tool tray)
  • Draw with a pen to scribble any diagram
  • Automatic outlines
  • Can just copy in images
  • Auto-saves everything
  • Can just start writing anywhere on the page.

It looks like it has a lot of potential, and provides a decively different niche than other office products (Word, FrontPage, Visio, or Excel) that may be used for the same task. I'll curious to check it out more.

Wednesday, November 1, 2006

SQL Tip: Concat entire column into a single CSV string

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

Sometimes in SQL, you'll want to concat an entire column's values into a single string.

For example, say you have a parent-child relationship (like state-city, or entity-code), and in a parent's list page, you want to display a column with the CSV string of all the children.

State City
IL Chicago
IL Springfield
IL Rockford
WI Madison

You can concatenate a list of values into a CSV string like "Chicago, Springfield, Rockford" by continually selecting into the same variable:

        declare @sCsv varchar(1000)
        set @sCsv = ''

        select @sCsv = @sCsv + City + ', '
        from MyTable
        where State = 'IL'; --any filter clause here

        --remove final ","
        if (Len(@sCsv) > 1)
                select @sCsv = substring(@sCsv,1,len(@sCsv)-1)
        return @sCsv