Want to follow this site? Here's the RSS feed.

Reusing .NET Assemblies in Silverlight

Saturday, December 20, 2008

Table of Contents

Introduction

Long before Silverlight 1.0 was released, it was actually called WPF/E or WPF Everywhere.  The idea was to allow you to create WPF like interfaces in your web browser.  This can be seen in a very small way in Silverlight 1.0.  All it provided was very basic primitive objects with the ability for interact with client-side technologies like JavaScript.  However, with Silverlight 2.0, Silverlight is actually more than what was originally promised with the term "WPF/E".  Silverlight is now far much more than a graphical technology.  All this stuff about Silverlight being "WPF for the Web" is more to make the marketing folks happy than anything else.

As a technology parallel to .NET, Silverlight is not part of the .NET family.  Rather, it essentially mirrors the .NET platform to create a new platform inside of a web browser where you have a mini-CLR and mini-Framework Class Library (FCL).  However, even though they are parallel technologies, you would suspect that Microsoft would allow some level of reuse between the two.  As it turns out, most topics are completely reusable.  Among other things, Silverlight has delegates, reference types, value types, a System namespace, and the ability to write code in both C# and VB.

Furthermore, despite the rumors, Silverlight also shares the exact same module and assembly format as .NET.  This may seem completely shocking to some people given the fact that Visual Studio 2008 doesn't allow you to reference a .NET assembly in a Silverlight project.  In reality, however, there's no technical reason for this prohibition.  There isn't a single byte difference between a Silverlight and .NET assembly.  One way to see this is by referencing a Silverlight assembly in a .NET project.  Just try it.  It works great.  So, why doesn't Visual Studio allow .NET assemblies in Silverlight projects?

To answer this, we need to understand that just because an optional helper tool (i.e. Visual Studio) doesn't allow something, that doesn't mean the technology itself doesn't.  In this case, the reason why Visual Studio allows a .NET project to reference Silverlight assemblies, but not the other way around is probably because .NET assemblies can normally do more.  For example, .NET has all kinds of XML related entities in its System.Xml assembly.  If Silverlight were to try to use this, it would blow up at runtime.  However, both Silverlight and .NET have an mscorlib assembly thus giving them a sense of brotherhood.  Having said that, Silverlight has the System.Windows.Browser assembly which, upon access in .NET, would make your .NET application explode!  Thus, the Visual Studio restriction laws are flawed.

Fortunately, there are ways around Visual Studio's fascist regime.  I'm going to talk about two different ways of reusing .NET assemblies and code in Silverlight.  The first technique is the more powerful assembly-level technique, while the second is more flexible file-level technique.  Each technique is useful for its own particular scenarios.  Please keep naive comments of "I'm ALWAYS going to..." and "I'm NEVER going to..." to yourself.  You need to make decisions of which of these techniques or possibly another technique to use on a case by case basis.

The Assembly-Level Technique

For this technique, you need to understand what's going on under the covers when you try to add a .NET reference to your Silverlight application in Visual Studio.  It's actually incredibly simple.  Visual Studio isn't a monolith that controls all your code from a centralized location; sometimes it uses plug-ins to do it's dirty work.

In this case, Visual Studio 2008 uses the Microsoft.VisualStudio.Silverlight .NET assembly.  In this assembly is the Microsoft.VisualStudio.Silverlight.SLUtil class which contains the IsSilverlightAssembly method.  When you add an assembly to a Silverlight Project, this method is called internally to see if your assembly is Silverlight.  If it is, it will add it.  If not, it won't.  It's just that simple.  But, given that the Silverlight and .NET assembly format is the same, how can it know?

You may be shocked to find out that the reason behind this is completely artificial: if the assembly references the 2.0.5.X version of the mscorlib assembly, then Visual Studio says that it's a Silverlight assembly!  This test is essentially all the IsSilverlightAssembly does.  Therefore, if you take your .NET 2.x/3.x assembly and change the version of mscorlib that your assembly references from 2.0.0.0 to 2.0.5.0, you may then add the assembly as a reference.  Now let's talk about this with a more hands on approach.

Below is the sample code we will be working with for this part of the discussion.  Say this code is placed in an empty .NET project.  When it is compiled, we will have an assembly.  Let's call it DotNet.dll.

using System;
//+
namespace DotNet
{
    public class Test
    {
        public String GetText()
        {
            return String.Format("{0} {1} {2} {3}", "This", "is", "a", "test");
        }
    }
}

Before we go any further, lets' discuss the state of the universe at this point.  If you ever try to solve a problem without understanding how the system works, you will at best be hacking the system.  Professionals don't do this.   Therefore, let's try to understand what's going on. 

The first thing you need to know is that when you add an assembly to a project in Visual Studio, you are simply telling Visual Studio to tell the compiler what reference you have so that when the compiler translates your code into IL, it knows what assemblies to include as "extern assembly" sections.  Even then, only the assemblies that are actually used in your code will have "extern assembly" sections.  Thus, even if you added reference every single assembly in your entire system but only use two, the IL will only have two extern sections (i.e. references assemblies).  The second thing you need to know is that no matter what, your assemblies will always have a reference to mscorlib.  This is the root of all things and is where System.Object is stored.

To help you understand this, let's take a look at the IL produced by this class.  To look at this IL, we are going to use .NET's ILDasm utility.  Reflector will not be your tool of choice here.  Reflector is awesome for referencing code, but not for working with it.  It's more about form than function.  With ILDasm we are going to run the below command:

ILDasm DotNet.dll /out:DotNet.il

For the sake of your sanity, use the Visual Studio command prompt for this.  Otherwise you will need to either state the absolute path of ILDasm or set the path.

This command will produce two files: DotNet.il and DotNet.res.  The res file is completely meaningless for our discussion and, therefore, will be ignored.  Here is the IL code in DotNet.il:

.assembly extern mscorlib
{
    .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
    .ver 2:0:0:0
}
.assembly DotNet
{
    /** a lot of assembly level attributes have been left out **/

    .hash algorithm 0x00008004
    .ver 1:0:0:0
}
.module DotNet.dll
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 
.corflags 0x00000001     

.class public auto ansi beforefieldinit DotNet.Test extends [mscorlib]System.Object
{
    .method public hidebysig instance string GetText() cil managed
    {
        .maxstack    4
        .locals init ([0] object[] CS$0$0000)
        IL_0000:    ldstr "{0} {1} {2} {3}"
        IL_0005:    ldc.i4.4
        IL_0006:    newarr [mscorlib]System.Object
        IL_000b:    stloc.0
        IL_000c:    ldloc.0
        IL_000d:    ldc.i4.0
        IL_000e:    ldstr "This"
        IL_0013:    stelem.ref
        IL_0014:    ldloc.0
        IL_0015:    ldc.i4.1
        IL_0016:    ldstr "is"
        IL_001b:    stelem.ref
        IL_001c:    ldloc.0
        IL_001d:    ldc.i4.2
        IL_001e:    ldstr "a"
        IL_0023:    stelem.ref
        IL_0024:    ldloc.0
        IL_0025:    ldc.i4.3
        IL_0026:    ldstr "test"
        IL_002b:    stelem.ref
        IL_002c:    ldloc.0
        IL_002d:    call  string [mscorlib]System.String::Format(string, object[])
        IL_0032:    ret
    }

    .method public hidebysig specialname rtspecialname 
         instance void    .ctor() cil managed
    {
        .maxstack    8
        IL_0000:    ldarg.0
        IL_0001:    call  instance void [mscorlib]System.Object::.ctor()
        IL_0006:    ret
    }
}

Right now we only care about the first section:

.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}

This ".assembly extern ASSEMBLYNAME" pattern is how your assembly references are stored in your assembly.  In this case, you can see that mscorlib is referenced using both it's version and it's public key.  For our current mission, all we need to do is change the second 0 to a 5.  The public key tokens used in Silverlight are completely different from the ones in .NET, but we are trying to fool Visual Studio, not Silverlight.  This is a compile-time issue, not a runtime-issue.  Speaking more technically, we don't care about the public key token because this information is only used when an assembly is to be loaded.  The correct mscorlib assembly will have already loaded by the Silverlight application itself long before our assembly comes on the scene.  So, in our case, this entire mscorlib reference is really just to make the assembly legal and to fool Visual Studio.

Once you make the change from 2:0:0:0 to 2:0:5:0, all you need to do is use ILAsm to restore the state of the universe (unlike Reflector with C#, ILAsm can put humpty dumpty back together again).  Here's our command for doing this (in this case the resource part is completely optional, but let's add it for completeness):

ilasm DotNet.il /dll /resource:DotNet.res /out:DotNet2.dll

You are now free to reference your .NET assembly in your Silverlight project or application.  As I've already mentioned, Silverlight and .NET have the same assembly format.  There's nothing in Silverlight that stops us from referencing .NET assemblies, it was only Visual Studio stopping us.

At this point you have just the basics of this topic.  However, it's not the end of the story.  As you should be aware, .NET's core assemblies use four-part names.  That is, they have a strong name.  This is used to disambiguate them from other assemblies.  That is, instead of the System assembly being called merely "System", which can easily conflict with other assemblies (obviously written by non-.NET developers who don't realize that System should be reserved), it's actually named "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089".  When you reference an assembly, you need to make sure to match the name, version, culture, and public key token.  When it comes to using .NET assemblies in Silverlight, this is critically important.

Let's say, for instance, that you created a .NET project which referenced and used entities from the System, System.ServiceModel, and System.Runtime.Serialization assemblies.  In this case, the IL produced by the .NET compiler will create the following three extern assembly sections:

.assembly extern System
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
  .ver 2:0:0:0
}
.assembly extern System.ServiceModel
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
  .ver 3:0:0:0
}
.assembly extern System.Runtime.Serialization
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
  .ver 3:0:0:0
}

Notice the public key token on each.  Here all three are the same, but for other .NET assemblies they may be different.  What's important here, though, is that the keys are used to identity the assemblies for .NET, not Silverlight.  Thus, even though you did add your .NET assembly to your Silverlight application, an exception would be thrown in runtime at the point where your application tries to access something in one of these assemblies.

The following shows you what would happen in the extreme case of trying to use the System.Web assembly in your Silverlight.  You would get the same error if you tried to access something in one of the above assemblies as well.

AssemblyException

As it stands, though, we can fix this just as easily as we fixed the mscorlib problem in Visual Studio.  All we need to do is open our IL and change the public keys and versions to the Silverlight versions.  Below is a list of the common Silverlight assemblies each with their public key token and version:

.assembly extern mscorlib
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Core
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Net
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Runtime.Serialization
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Windows
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}
.assembly extern System.Windows.Browser
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E)
  .ver 2:0:5:0
}

//+ note the different public key token in the following
.assembly extern System.ServiceModel
{
  .publickeytoken = (31 BF 38 56 AD 36 4E 35)
  .ver 2:0:5:0
}
.assembly extern System.Json
{
  .publickeytoken = (31 BF 38 56 AD 36 4E 35)
  .ver 2:0:5:0
}

Just use the same ILDasm/Edit/ILAsm procedure already mentioned to tell the assembly to use the appropriate Silverlight assemblies instead of the .NET assemblies.  This is an extremely simple procedure consisting of nothing more than a replace, a procedure that could easily be automated with very minimal effort.  It shouldn't take you much time at all to write a simple .NET application to do this for you.  It would just be a simple .NET to Silverlight converter and validator (to test for assemblies not supported in Silverlight).  Put that application in your Post Build Events (one of the top 5 greatest features of Visual Studio!) and you're done.  No special binary hex value searching necessary.  All you're doing is changing two well documented settings (the public key token and version).

For certain assemblies, this isn't the end of the story.  If your .NET assembly has a strong name, then by modifying it's IL, you have effectively rendered it useless.  Aside from disambiguation, strong names are also used for tamper protection.  You can sort of think of them as a CRC32 in this sense.  If you were to modify the IL of an assembly with a strong name, you would get a compile-time error like the following:

StrongNameException 

However, as you know by the fact that we have looked at the raw text of the source code with our own eyes, the strong name does absolutely no encryption of the IL.  That's one of the most common misconceptions of strong names.  They are not used as for public key encryption of the assembly.  Therefore, we are able to get around this by removing the public key from our assembly before using ILAsm.  Below is what the public key will look like in your IL file.  Just delete this section and run ILAsm.

.publickey = (00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00
              00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00
              37 3C 5A 7F 6D B6 3F 30 D8 3F DE E3 17 FE E5 2E
              68 43 16 A9 7C 42 69 5A 05 52 E6 73 C5 AC 58 7E
              B0 00 9F DC 1B 0A 78 57 79 12 79 53 E1 60 EB C9
              ED 49 7C 8C 73 1B 01 A7 BA 57 79 B5 53 83 8B CA
              8D F8 6F 3B BD A5 E4 BA 6A 12 B9 52 F2 E9 A3 FC
              42 17 E4 33 97 92 DC 21 30 57 B9 D3 63 7A F2 43
              73 42 70 18 89 8B 44 B9 D4 5A BA A9 21 A3 D9 E0
              86 20 3C 30 01 A9 B9 BB F4 D8 79 B7 7D 56 5A A9)

Upon using ILAsm to create the binary version of the same IL, you will be able to add your assembly, compile and run your application without a problem.  However, you can take this one step further by telling ILAsm to sign the assembly using your original strong name key.  To do this, just use the key command line option to specify the strong name key you would like to use.  Below is the new syntax for re-signing your assembly:

ILAsm DotNet.il /dll /resource:DotNet.res /out:DotNet11.dll /key=..\..\MyStrongNameKey.snk

At this point you have a strongly-named Silverlight assembly createdrom your existing .NET assembly.

Now, before moving on to explain a more flexible method of reuse, I want to cover a few miscellaneous topics.  First, for those of you who know some IL and are trying to be clever to make this process even simpler, you may think you could just do the following:

.assembly extern mscorlib { auto }

This won't work as ILAsm will look for "auto" and place the 2.0.0.0 version in it's place, thus leaving you right where you started.  Also, don't even think about leaving the entire mscorlib part off either.  That won't fool anyone since ILAsm will detect that it's missing and add it before continuing the assembly process.  You need to explicitly state that you want assembly version 2.0.5.0.

Second, you need to think twice before you add a Silverlight assembly to a .NET application.  In the Visual Studio world, if you add a .NET assembly, you add only that assembly. But, in the that assembly is a Silverlgiht assembly, then you will see all of the associated Silverlight assemblies added for each culture you have.  When I did this on my system, exactly 100 extra files were added to my Bin folder!  That's insane.  So, perhaps the Visual Studio team put a "Add Reference" block in the wrong place!

The File-Level Technique

Now all of this is great.  You can easily access your .NET assemblies in Silverlight.  But, many times this isn't even what you need.  You need to remember that every time you reference an assembly in Silverlight, you increase the size of your Silverlight XAP package.  Whereas .NET and Silverlight will only register assembly references in IL when they are actually used, Silverlight will package referenced assemblies in the XAP file regardless of use.  They assemblies will also be registered in the AppManifest.xaml file as an assembly part.  Though the XAP file is nothing more than a ZIP file, thereby shrinking the size of the assembly, this still spells "bloat" if all you need is just a few basic types from an assembly that's within your control.  For situations like this, there's a much simpler and much more flexible solution.

The solution to this again deals with understanding the internals of your system: whenever you add a file to your project in Visual Studio, all you are really doing is adding a file to an ItemGroup XML section in the .NET project file.  This is just a basic text file that describes the project.  As you may have guessed, the ItemGroup section simply contains groups of items.  In the case of compilation files (i.e. classes, structs, enums, etc...), they are Compile items.  Here's an example of a snippet from a .NET project:

<ItemGroup>
  <Compile Include="Client\PersonClient.cs" />
  <Compile Include="Agent\PersonAgent.cs" />
  <Compile Include="Properties\AssemblyInfo.cs" />
  <Compile Include="Configuration.cs" />
  <Compile Include="Information.cs" />
  <Compile Include="_DataContract\Person.cs" />
  <Compile Include="_ServiceContract\IPersonService.cs" />
</ItemGroup>

Given this information, all you need to do is (1) create a Silverlight version of this assembly, (2) open the project file and (3) copy/paste in the parts you want to use in your Silverlight project with the appropriate relative paths changed.  This will create a link from the Silverlight project's items to the physical items.  No copying is done.  They are pointing to the exact same file.  When they are compiled, there is no need to do any IL changes in your assemblies at all since the Silverlight assembly will be Silverlight and the .NET assembly will be .NET.

Now that you know about this under-the-covers approach, you should be aware that this is actually a fully supported option in Visual Studio.  Just go to add an existing item to your project and instead of clicking add or just hitting enter, hit the little arrow next to add and select "Add As Link".  This will do the exact same thing as what we did in our bulk copy/paste method in the project file.  Here's a screen shot of the option in Visual Studio:

AddAsLink

What may be more interesting to you is that this feature may be used anywhere in .NET.  You can use this to reuse any files in your entire system.  It's a very powerful technique to reuse specific items in assemblies.  It comes it very handy when two assemblies need to share classes and creating a third assembly which both may access leads to needless complexity.

Conclusion

Given these two techniques, you should be able to effectively architect a solution that scales to virtually any number of developers.  The first technique is easy to deploy using a custom utility and post build events, while the second is natively supported by any good version control systems.  Keep in mind though, that when using the first technique you may not always need to do this on every build.  The best approach I've seen for this is to have a centralized location on a network share that contains nightly (or whatever) builds of core assemblies.  Then, a login script will copy each of the assemblies to each developers machine.  This will cut down on the complexity of compilation and dramatically lower the time to compile any solution.

Regardless of which technique you use, you should feel a sense of freedom knowing of their existence.  This is especially true if all you are doing is trying to share data contracts between .NET and Silverlight.  As I've mentioned in my popular 70+ page "Understanding WCF in Silverlight 2" document, the "Add Service Reference" feature is not something that should be used in production.  In fact, it's painful in development as well.  Using the techniques described here, you can easily share your data contracts between your .NET server and the Silverlight client without the FrontPage/Word 95 style code generation.  For more information on this specific topics, see the aforementioned document.

Links

kick it on DotNetKicks.com

(5 Comments)

FREE Silverlight Training on the Web

Tuesday, December 16, 2008

In case you didn't know it, knowledge is free.  In fact, it always has been.  Some cultures make it hard to obtain, but it's free nonetheless.  The Internet gives you extremely close access this knowledge.  You can randomly choose just about any topic in the world and find at least one article, blog posting, or Wikipedia entry on the topic.  In fact, when I was in college I only showed up once to my Kansas State University Physics II class.  Instead I kepted up with the class from home by watching the MIT OpenCourseWare video courses.  When it comes to Internet-related technologies like Silverlight, knowledge is even easier to find.

I see all kinds of courses by some of the biggest training companies offering all sort of great Silverlight courses.  However, these are extremely pricey.  There are also many books on Silverlight coming out.  Again, not free.  But think about it, how do you think the trainers and authors get their information?  When I was offered my Silverlight 2 book deal (since being on a deadline sucks, I turned it down), where do you think I would get my information?  It's all free online.  Here in December 2008, there are all kinds of amazing free resource for learning Silverlight.  You do not need training.  You do not need to buy a book.  Here are some of these resources that I've found this year to help bring you from ground zero to being a Silverlight master:

First, there's the 53-part video series at Silverlight.net.  This series just about every single topic you will ever see in your Silverlight career.  However, I would consider these to be at the basic level.  They cover the fundamentals of each topic, give great tips, and progressively give more interesting examples as the videos progress.  If all you are going to be doing is under-using Silverlight 2 as an RIA platform and for general [boring] UI development, then this series may be 90% of what you need.  Link: http://silverlight.net/Learn/videocat.aspx?cat=2

Second, there's the 44-part video series from Mike Taulty.  This is the guy behind the MSDN Nuggets videos.  These videos are more at the intermediate-advanced level.  It's also somewhat focused at "under-the-covers" development.  Mike doesn't do drag-n-drop videos.  He teaches real technology.  Whereas the previous series will discuss concepts and how to do things "out of the box", Mike's videos show you how to work with things at a more mechanical level, thus giving you a much greater level of control.  If you don't know the topics he's discussing in the videos, you don't know Silverlight.  Link: http://channel9.msdn.com/posts/Dan/Mike-Taulty-44-Silverlight-20-Screencasts/

Third, let's not forget that Microsoft has its annual Mix and PDC conferences.  Microsoft makes sure that the content for these conferences are freely available online.  The Mix videos are very specific and, therefore, should probably be watched on an as-needed basis.   You can just follow the link to see the wide variety of topics.  Since it's at a conference, however, some of the information will be marketing-speaking, but there's a lot of good stuff in the videos as well.  The PDC however is much less marketing-ish and there were a few Silverlight 2 sessions.  Links: http://silverlight.net/learn/videocat.aspx?cat=8 and https://sessions.microsoftpdc.com/public/timeline.aspx.

Fourth, if you're the reading-type, then you may prefer the Silverlight 2 e-book at learn-silverlight-tutorial.com.  This e-book covers a ton of information.  Much like the 53-part series, I would mark this down as basic-level.  It covers a touches on a wide variety of topics.  However, much of the information is just that: "a touch".  It's not very deep, but it's rather wide.  Link: http://www.learn-silverlight-tutorial.com/

Fifth, Microsoft has always been good about providing QuickStarts.  These are kind of a cross between visual, text, and hands-on learning.  These are also the typical go to card for any one new to anything.  The ASP.NET quick starts are still incredibly popular these many years later.  The Silverlight ones are quite well done as well.  The topics are basic-intermediate and range from topics like general UI controls to cooler stuff like JavaScript/DOM interop.  However, you may feel completely free to absolutely ignore the completely worthless "web services" section.  Whoever wrote that thought he or she was writing about the hopelessly-flawed ASMX, not the image-of-beauty WCF and, therefore, didn't even remotely bother to obey the most fundamental of WCF purposes and practices (i.e. keep your address, binding, and contract away from your implementation!) Link: http://silverlight.net/quickstarts/

Speaking of WCF, the last resource I want to mention is my document entitled "Understanding WCF in Silverlight 2".  This one has received a lot of attention since I wrote it in November 2008.  In fact, it's now listed on the WCF MSDN home page.  It's there because I cover WCF from the ground up for both .NET and Silverlight in a very deep manner.  If you are new to WCF, SOA, or Silverlight, then this is a good place to start (of course, no bias here.)  I wrote this document to help both people new to WCF and Silverlight as well as those who have been working either either for a while.  Even if you're not too serious about Silverlight, you should still read this detailed document to understand WCF better.  I don't play around with introductory nonsense, I hit the ground running with best-practices and proper architectural principles.  Link: http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2

Though it's not a straight learning resource, I support I would also like to mention that you can always check out the Silverlight tag in my Delicous account: http://delicious.com/quantum00/silverlight.  However, keep in mind that just because I bookmark something, it doesn't mean I'm recommending the resource.  It just means it was interesting and/or provided some value to me.  You can expect this to be updated for the months to come.  I live off of my delicious account.

Another thing I would like to mention is that if you know WPF and web development, then you almost get Silverlight knowledge naturally.  Silverlight is essential a subset of WPF for the web.  You just take WPF, rip out a bunch of features, add just a handful of topics, move it to the web, and you have Silverlight.  Much of your skills are reusable if you already know WPF.  Actually, a lot of your skills are reusable if you're a .NET developer in general.  Just whip open Reflector and start looking through the framework, you'll see that there's a lot less than what's in the .NET framework, thus requiring much less learning time.

So, don't waste your money on books.  The blog is the new book.  Don't bother asking your employer for Silverlight training.  OK, well, if you just want some time off from work, sure, go ahead and ask.  Really, though, these resources will give you what you need for your Silverlight development.  In fact, if you were to compare the syllabus for an expensive course with the topics found in the first two sections of videos mentioned (97 of them!), you will see that the ROI for the course is virtually non-existent.

Links Summary

Tim Ferris - Trial by Fire

Tuesday, December 2, 2008

This is beyond awesome.  Tim Ferris, author of one of the greatest books ever written, Four Hour Work Week, has announced that he has a new show called Trial by Fire.  I'm incredibly excited to hear this.  Time Ferris is one of my core role models for just about every area of life.  I regularly reread and reference his Four Hour Work Week book and am constantly studying his blog.  In fact, when you read my NetFXHarmonics web site, you are reading Ferris principles applied to the development world.

He calls himself a life hacker.  What it takes others years to master, he tries to learn in days.  This is the primary purpose of his Trial by Fire show.  It's also something I've been studying for years through my research in accelerated learning and experience induction.  Ferris sometimes mentions that his technique is to deconstruct, streamline, and remap.  If you read my recent posts on streamlining WCF and WCF in Silverlight, you've seen a taste of how you can apply these principles to development.  It's how I personally think, act, and speak.

For more information on Tim Ferris, his show, or his book, check out his blog at http://www.fourhourblog.com/.  His blog is essentially an extension to his book, Four Hour Work Week, a book every single person in the world needs to read and reread.  You absolutely must buy this book.  Get it in print or get it in audio, just get it.

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 License.

Built on Themelia Pro 2.0

Mini-icons are part of the Silk Icons set of icons at famfamfam.com