Sep 30 2011

Getting C# Source Code From a COM Interop Assembly With ILSpy

Category: .NET | Tips & Tricks | COMDavid @ 15:43

Many of you were no doubt ticked when RedGate decided to stop providing Reflector as a free tool.  Well, this post is not designed to harp on that or talk about how Redgate backtracked on that decision.  Instead, let’s talk about a great replacement for it that is free and open source! 

This great new tool is called ILSpy.  It has a great feature that will let you output the disassembly code to actual C# files.  This comes in super handy if you have a COM Interop assembly that you need to modify. I ran into this situation when working on a project leveraging the VirtualBox API.

The great thing is that it is supper easy to do.  Once you open the interop assembly in ILSpy simply select the assembly node in the treeview and then on the File menu select Save Code…  You will then be prompted to save a C# project file.  Once you do that it will generate the project file and will create a .cs file per object  in the assembly.  And that is it!

Tags: , ,

Mar 22 2011

An Old Trick for Speeding up .NET Compact Framework Builds: PlatformVerificationTask

Category: .NET | Tips & Tricks | Compact FrameworkDavid @ 11:48

OK! I know that most new mobile development is occurring on Windows Phone 7, iPhone or Android, but I have no other choice than Windows Mobile 6 for the application I’m currently working on due to customer requirements.  So, here I am stuck back in VS 2008 developing a mobile application for Law Enforcement.  In the past I played around with mobile development in my spare time, but never had to do any long term development for it.  Since starting on this current project I noticed how long it took for my builds to deploy to the emulator and test devices for debugging.  Deployment was taking from a few minutes to over 5 minutes at times.  Well, you know as well as I do what that can do to developer productivity!

Now,  I’m the type of developer that codes a chunk of code, builds, tests, and repeats the process in rapid succession so I was really not having any fun. So to figure out what was going on I set the Build output to “Diagnostic” in my Build options and hit F5.  Well, I noticed that it was hanging on a build task called “PlatformVerificationTask”.  Well, after digging around a little on Bing. I found this old blog post.  The short of it is that the Platform Verification Task does a check on your assemblies at build time to make sure there are no unsupported properties, methods or events in your code.  This process can really slow down the build process on large applications that have multiple DLLs. (Like my project does!)

So, what the solution?  It’s a good ‘ole file editing trick.  All you need to do is edit the file located at %windir%\Microsoft.NET\Framework\v2.0.50727\Microsoft.CompactFramework.Common.Targets and find the node:

<Target
    Name="PlatformVerificationTask">
    <PlatformVerificationTask
        PlatformFamilyName="$(PlatformFamilyName)"
        PlatformID="$(PlatformID)"
        SourceAssembly="@(IntermediateAssembly)"
        ReferencePath="@(ReferencePath)"
        TreatWarningsAsErrors="$(TreatWarningsAsErrors)"
        PlatformVersion="$(TargetFrameworkVersion)"/>
</Target>

 

Add the following attribute to the <PlatformVerificationTask"> node:

Condition="'$(DoPlatformVerificationTask)'=='true'"

Now restart Visual Studio 2008 and check out how much faster your build is!

Tags: , ,

Dec 1 2009

Silverlight 4 Overview @ PDC 2009

Category: .NET | SilverlightDavid @ 13:41

If you haven't been paying attention to Silverlight lately then you may not know that Microsoft released a beta of Sivlerlight 4 during PDC.  Here is a great webcast, presented by Karen Corby, that gives an overview of the new Silverlight 4 features.  Check it out when you get a chance...No, strike that, go right now and watch it!

Tags: ,

Nov 16 2009

Got ViewState?

Category: .NET | ASP.NET | Best Practices | Tips & TricksDavid @ 10:58

A few months ago I wrote a couple of posts on Managing Session Variables in ASP.NET using a Proxy. Since then I have thought about the need to write a post addressing the use of the ViewState as well.  As with SessionState,  ViewState is essential just a Dictionary of String, Object pairs.  This means that at design time you have to do a fair amount of type casting to use the objects you store in ViewState in a strongly typed manner.  It also introduces many of the same issues as using the native SessionState, such as:

  • the inability to know where you are using a given ViewState variable in your code.
  • the potential for mistyping a ViewState key when putting an object in ViewState or retrieving.
  • the increase in code to check for null values returned from ViewState.

Each of these issues is a pain to deal with on their own, but when the issues are compounded over a complex page then it really can make for a bad experience when developing.  The solution to this problem that I propose is to use custom properties on the page to access the various objects that are stored in ViewState.  Below is an example of a code behind page that illustrates how to do this.  This example assumes you have a class Person that defines properties of FirstName, LastName and ID, as well as a web page with two textboxes and a button.

   1: Partial Public Class _Default
   2:    Inherits System.Web.UI.Page
   3:  
   4:  
   5: #Region " Fields "
   6:  
   7:    Private Const _personViewState As String = "MyPerson"
   8:    Public Const QueryStringParameterPersonID As String = "pid"
   9:  
  10: #End Region
  11:  
  12: #Region " Properties "
  13:  
  14:    Public Property Person() As Person
  15:       Get
  16:          If ViewState(_personViewState) Is Nothing Then ViewState(_personViewState) = New Person
  17:          Return CType(ViewState(_personViewState), Person)
  18:       End Get
  19:       Set(ByVal value As Person)
  20:          ViewState(_personViewState) = value
  21:       End Set
  22:    End Property
  23:  
  24: #End Region
  25:  
  26: #Region " Methods "
  27:  
  28:    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  29:       If Not String.IsNullOrEmpty(Page.Request.QueryString(QueryStringParameterPersonID)) Then
  30:          'Get your user from your datastore and populate the Person Property with the returned user.
  31:          Person = PersonDAO.GetPersonByID(CInt(Page.Request.QueryString(QueryStringParameterPersonID)))
  32:       End If
  33:  
  34:       FirstNameTextbox.Text = Person.FirstName
  35:       LastNameTextBox.Text = Person.LastName
  36:  
  37:    End Sub
  38:  
  39:    Protected Sub SaveButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles SaveButton.Click
  40:       Person.FirstName = FirstNameTextbox.Text.Trim
  41:       Person.LastName = LastNameTextBox.Text.Trim
  42:  
  43:       'Persist your Person to your datastore, etc.
  44:    End Sub
  45:  
  46: #End Region
  47:  
  48: End Class

In this example you can see how I have abstracted the access to my ViewState Person object into a property that always returns an instance of a Person. You can of course have this property return null (Nothing) if you need or prefer that for your own development.  Either way you are still eliminating the direct reference to the ViewState allowing you to program against a strongly typed object.  As I did in my SessionProxy posts, I am using a private constant to hold the string value of my key to eliminate the chance of mistyping this value when using it in multiple places.

Another technique that I would like to point out in this post is the use of public constants to represent the string value of the query parameter names for this page.  By exposing a constant representing this value I then make it possible for other developers to easily see the parameters that my page accepts.  If they utilize the constant it will also allow me to change the actual string value of my parameter name at any point in time without affecting the functionality of my page. (I realize this is a big “If” that is reliant on team standards.)

Tags: , , , , ,

Aug 5 2009

Managing Session Variables in ASP.NET using a Proxy – Part 2

Category: .NET | Architecture | ASP.NET | Best Practices | Tips & TricksDavid @ 15:54

In my last post I gave an example of using the Proxy Design Pattern to manage your ASP.NET Session.  In this post I wanted to refine that proxy class through some refactoring and add some additional functionality to it that remove Session variables and also allow us to use the proxy to clear or abandon the Session as a whole. We will also create a mechanism for grouping Session variables into related objects in the SessionProxy.

First I want to add a private property that will allow me to eliminate some of the verbosity in my code.  I’ll add a private static property that encapsulates the current HTTPSessionState object.  We can then use that property to refactor our other properties so they are more readable.

   1: private static HttpSessionState Session { get { return HttpContext.Current.Session; } }

Next we’ll add some code into our properties that will check for the value being set and remove the Session variable from the Session object if necessary.  As an example I’ll use a new Property of type String.

   1: public static String CategoryName
   2: {
   3:    get 
   4:    {
   5:       if (Session[CATEGORYNAME] == null) { return String.Empty; }
   6:       return (String)Session[CATEGORYNAME];
   7:    }
   8:  
   9:    set 
  10:    {
  11:       if (String.IsNullOrEmpty(value)) { Session.Remove(CATEGORYNAME); }
  12:       else { Session[CATEGORYNAME] = value; }
  13:    }
  14: }

Now I want to add a few methods to allow me to use the SessionProxy to Clear the current Session or Abandon it.

   1: #region Methods
   2:  
   3: public static void Clear() { Session.Clear(); }
   4:      
   5: public static void Abandon() { Session.Abandon(); }
   6:      
   7: #endregion

At this point I feel that I have a pretty good proxy class that allows me to leverage my ASP.NET Session in a strongly type manner and to easily see what I am storing in the Session and what their types are.

However, in using this solution in a production application I have found that my list of properties has grown longer than I would like. There were close to two dozen at last count and all the Session variables have not been migrated to use the proxy.  I found myself increasingly tired of seeing all those properties each time I accessed the class.  On top of that some of the names were getting rather long in an effort to give them meaningful names.  To resolve this I implemented several properties on the SessionProxy that were child proxy objects.  To make things a bit easier I created a base class called SessionProxyChildProxyBase.  Here’s the code in full for that base class.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.SessionState;
   6:  
   7: public abstract class SessionProxyChildProxyBase
   8: {
   9:  
  10:   #region Properties
  11:  
  12:   protected HttpSessionState Session { get { return HttpContext.Current.Session; } }
  13:  
  14:   #endregion
  15:  
  16: }

You will note a few points on this class.  Unlike the SessionProxy class the SessionProxyChildProxyBase class is an abstract class.  We don’t want to allow others to implement this base class outside of our library so that the SessionProxy class now becomes a proxy for this class as well as for the ASP.NET Session.  It also contains a protected Session property that will facilitate a decrease in code verbosity.

Now we will leverage this base class and create derived classes that will contain related properties.  In your application you may provide a central location for entering search criteria but you pass those criteria via the Session to a page that actually displays the search results.  Let’s create a child proxy class to organize the various values being passed.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5:  
   6: public class SearchSessionProxy: SessionProxyChildProxyBase
   7: {
   8:  
   9:   #region Fields
  10:  
  11:   private const String SEARCHTEXT = "SearchText";
  12:   private const String SEARCHTYPENAME = "SearchTypeName";
  13:   
  14:   #endregion
  15:  
  16:   #region Properties 
  17:  
  18:   public String Text
  19:   {
  20:      get
  21:      {
  22:         if (Session[SEARCHTEXT] == null) { return String.Empty; }
  23:         return (String)Session[SEARCHTEXT];
  24:      }
  25:  
  26:      set
  27:      {
  28:         if (String.IsNullOrEmpty(value)) { Session.Remove(SEARCHTEXT); }
  29:         else { Session[SEARCHTEXT] = value; }
  30:      }
  31:   }
  32:  
  33:   public String TypeName
  34:   {
  35:      get
  36:      {
  37:         if (Session[SEARCHTYPENAME] == null) { return String.Empty; }
  38:         return (String)Session[SEARCHTYPENAME];
  39:      }
  40:  
  41:      set
  42:      {
  43:         if (String.IsNullOrEmpty(value)) { Session.Remove(SEARCHTYPENAME); }
  44:         else { Session[SEARCHTYPENAME] = value; }
  45:      }
  46:   }
  47:  
  48:   #endregion
  49:  
  50:   #region Constructors
  51:  
  52:   internal SearchSessionProxy() { }
  53:  
  54:   #endregion
  55:  
  56: }

Now we need to add some code to our SessionProxy class to leverage this new class.  The first task is to add a private static field of type SearchSessionProxy.

   1: #region Fields
   2:  
   3: private static SearchSessionProxy _searchProxy = new SearchSessionProxy();
   4:  
   5: #endregion

Next we will create the property to access the field.

   1: public static SearchSessionProxy Search { get { return _searchProxy; } }

And that’s it!  Now we call utilize our SessionProxy with our new child proxy classes for organization and grouping so that we can doing something like this in our web app code…

   1: public void DoSomething() 
   2: {
   3:  SessionProxy.Search.Text = "Search Text entered by user";
   4:  SessionProxy.Search.TypeName = "Product Search";
   5:  SessionProxy.ProductID = 0;
   6:  Response.Redirect("SearchResults.aspx");
   7: }

Tags: , , , ,

Jul 21 2009

Managing Session Variables in ASP.NET using a Proxy

Category: David @ 14:51

Every developer who has ever worked with ASP.NET in a large solution knows how quickly Session variables can get out of control.  From the lack of strongly typed references to the potential misspellings of the variable names, the problems are always with us.  The good news is that there is a better way to handle objects in the Session.  The key is to develop a proxy class that will provide a set of strongly typed properties to store and retrieve objects in the HTTPSessionState object.

The Gang of Four defines the Proxy Structural Pattern as an object that serves to “Provide a surrogate or placeholder for another object to control access to it.”  A proxy is a fantastic way to provide abstraction in any application and will allow us to create a method for leveraging an ASP.NET Session object in a powerful way.

To begin with let’s create a static class (or NotInheritable in VB.NET) called SessionProxy.  The code will look something like this:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5:  
   6: public static class SessionProxy
   7:    {
   8:  
   9:       #region Properties
  10:  
  11:       public static int OrderID { 
  12:          get
  13:          {
  14:             return (int)HttpContext.Current.Session["OrderID"];
  15:          }
  16:  
  17:          set
  18:          {
  19:             HttpContext.Current.Session["OrderID"] = value;
  20:          }
  21:       }
  22:  
  23:       public static int ProductID 
  24:       {
  25:          get 
  26:          {
  27:             return (int)HttpContext.Current.Session["ProductID"];
  28:          }
  29:  
  30:          set
  31:          {
  32:             HttpContext.Current.Session["ProductID"] = value;
  33:          }
  34:       }
  35:  
  36:       #endregion
  37:  
  38:    }

 

You will notice in this initial code that we are typing the Session variable keys multiple times in each property definition.  Although this is a workable solution we still open ourselves up to the possibility of mis-spelling the two instances of the key.  So, let’s refactor our class a bit…

   1: public static class SessionProxy
   2:    {
   3:       #region Constants
   4:  
   5:       private const string ORDERID = "OrderID";
   6:       private const string PRODUCTID = "ProductID";
   7:  
   8:       #endregion
   9:  
  10:       #region Properties
  11:  
  12:       public static int OrderID { 
  13:          get
  14:          {
  15:             return (int)HttpContext.Current.Session[ORDERID];
  16:          }
  17:  
  18:          set
  19:          {
  20:             HttpContext.Current.Session[ORDERID] = value;
  21:          }
  22:       }
  23:  
  24:       public int ProductID 
  25:       {
  26:          get 
  27:          {
  28:             return (int)HttpContext.Current.Session[PRODUCTID];
  29:          }
  30:  
  31:          set
  32:          {
  33:             HttpContext.Current.Session[PRODUCTID] = value;
  34:          }
  35:       }
  36:  
  37:       #endregion
  38:  
  39:    }

 To utilize this in your code simply add a reference to the namespace where the SessionProxy exists and get or set the property through the class (ie. SessionProxy.ProductID = 123;).

Now we have a method for accessing our Session in a strongly typed manner and we are also able to see exactly what variable we have defined in our ASP.NET application by simply looking at the class definition of our SessionProxy.

Another advantage of using a proxy class like this is that it allows you to abstract your storage method as well.  If you want to use SQL Server Session or use a shared Session technology across multiple servers, all you need to do is change the property getter and setter logic and the rest of your application remains completely unchanged.

In Part 2 we will explore some enhancements to the SessionProxy.

Tags: , , , ,

Mar 26 2009

Accidental Singletons in Collection-Type Dependency Property

Category: .NET | Dependency Property | SilverlightDavid @ 12:00

Dependency Properties are a unique and powerful feature of WPF/Silverlight though they are normally transparent to you and you will, for the most part, not worry about them.  However, there are times when creating a Custom Dependency property will be the precise solution to your problem.  Sometimes you will need to create a dependency property that is a collection-type.  Now there is a very important point that you need to watch when creating a dependency property of this type, and that is the unintended creation of a singleton value.

Let’s see how this works and how you can resolve the issue.

(Insert here the obligatory creation of a temporary Silverlight application.)

After creating my temp application I created two classes.  The first is a person class.  The second is a Family classes that exposes a Members property that is backed by a dependency property and is of the type List<Person>.

   1:  using System;
   2:  using System.Net;
   3:  using System.Windows;
   4:  using System.Windows.Controls;
   5:  using System.Windows.Documents;
   6:  using System.Windows.Ink;
   7:  using System.Windows.Input;
   8:  using System.Windows.Media;
   9:  using System.Windows.Media.Animation;
  10:  using System.Windows.Shapes;
  11:  using System.Collections.ObjectModel;
  12:  using System.Collections.Generic;
  13:   
  14:  namespace SilverlightApplication1
  15:  {
  16:      public class Family    : DependencyObject
  17:      {
  18:          public static readonly DependencyProperty MembersProperty = DependencyProperty.Register(
  19:              "Bars",
  20:              typeof(List<Person>),
  21:              typeof(Family),
  22:              new PropertyMetadata(new List<Person>()));
  23:          
  24:          #region Properties
  25:   
  26:          public List<Person> Members
  27:          {
  28:              get { return (List<Person>)GetValue(MembersProperty); }
  29:              set { SetValue(MembersProperty, value); }
  30:          }
  31:   
  32:          #endregion
  33:   
  34:      }
  35:   
  36:      public class Person
  37:      {
  38:          #region Properties
  39:   
  40:          public string FirstName { get; set; }
  41:          public string LastName { get; set; }
  42:   
  43:          #endregion
  44:   
  45:          #region Constructors
  46:   
  47:          public Person(string firstName, string lastName) 
  48:          {
  49:              FirstName = firstName;
  50:              LastName = lastName;
  51:          }
  52:   
  53:          #endregion
  54:      }
  55:  }

 

In the application I created a simple method that creates two family objects and adds 3 members to the first and 2 members to the second.  I then populate two variables with the corresponding Count from each of the Member property lists like so.

   1:  private void Button_Click(object sender, RoutedEventArgs e)
   2:  {
   3:      Family fam1 = new Family();
   4:   
   5:      fam1.Members.Add(new Person("David", "Risko"));
   6:      fam1.Members.Add(new Person("Wife", "Risko"));
   7:      fam1.Members.Add(new Person("Kid1", "Risko"));
   8:   
   9:      Family fam2 = new Family();
  10:   
  11:      fam2.Members.Add(new Person("John", "Doe"));
  12:      fam2.Members.Add(new Person("Jane", "Doe"));
  13:   
  14:      int fam1Count = fam1.Members.Count();
  15:      int fam2Count = fam2.Members.Count();
  16:  }

After placing a breakpoint at line 16 I investigated our two count variables.  As you can see from the screenshot below we get an unexpected result where both Family objects show that they have 5 members each.  Our code clearly adds 3 members to the first family and 2 to the second, so how is this happening?

AccidentalSingleton1

The key to this is that we have defined a default value for our dependency property in the PropertyMetadata object when we called the Register method (line 22 in first code block).  Our Member list is a reference type and so therefore the default value set in the PropertyMetadata is not a default value per Family instance but rather is is the default value for all instances of our Family.  This is not the functionality that we are going to want in the vast majority of situations.  We need an instance specific list backing our Members property and fortunately there is a straight forward solution.  The key is to set your property to a new instance of its type in your constructor.  Here is the new code for my Family class constructor that accomplishes this.

   1:  #region Constructors
   2:   
   3:  public Family() : base()
   4:  {
   5:      Members = new List<Person>();
   6:  }
   7:   
   8:  #endregion

Now when we run our application we get the following values in our count variables:

AccidentalSingleton2

As you can see by simply re-initializing our dependency property value in our constructor we get the per instance functionality that we want and need.

Now when your out creating those custom dependency properties for collection-typed values you won’t get caught off guard.

NOTE: After typing this post I found the reference documentation on MSDN that actually covers this from a WPF perspective.  The resolution in WPF is slightly different but still applicable.

Tags: , ,

Mar 16 2009

The Shadow Knows! – The finer Nuisances of the VisualBasic.NET Shadows Keyword

Category: .NET | VisualBasic.NETDavid @ 15:22

I suspect that most people don’t often use the Shadows keyword.  I happened to be using it to develop a custom control because the base class I was inheriting from does not declare one of its properties as Overridable.  My control was inheriting from a StackPanel in Silverlight.  I wanted to limit the type of controls that could be placed inside of my control so I shadowed the StackPanel.Children property, which is of type List(Of UIElement), with a Children property of type List(Of CustomType). 

Initially that seemed to work.  It compiled without error or warning so I thought I was good to go.  Then the UI came up and I realized that things were not what they seemed to be.  The objects that I defined in my XAML for test were showing up, but none of the objects I added programmatically were.  Further more, the collection that was behind my custom property only contained the objects I added programmatically while the property on my StackPanel base contained the items I had defined in XAML.  WHAT?!  How is that?

The difference is in how Shadows works and how the Silverlight runtime was viewing my custom type.  When you shadow a property/method, the original property/method is hidden when your object is viewed as your custom type.  However, if your object, which is of your custom type, is cast to the type of the base class then the base class property becomes visible and is the one that gets accessed.  Let me explain with an example.

I have created three classes. Class A is the base class which B derives from A, and class C derives from class B. Like so…

Public Class A
    ReadOnly Property FirstName() As String
        Get
            Return "A"
        End Get
    End Property

    Overridable ReadOnly Property Lastname() As String
        Get
            Return "1"
        End Get
    End Property
End Class
 
Public Class B
    Inherits A

    Shadows ReadOnly Property FirstName() As String
        Get
            Return "B"
        End Get
    End Property

    Overrides ReadOnly Property Lastname() As String
        Get
            Return "2"
        End Get
    End Property
End Class
 
Public Class C
    Inherits B

    ReadOnly Property FirstName() As String
        Get
            Return "C"
        End Get
    End Property

    Overrides ReadOnly Property Lastname() As String
        Get
            Return "3"
        End Get
    End Property
End Class
 
You will notice that the Firstname property on Class A is not declared as Overridable.  This means that to replace it’s functionality I must declare it as Shadows in my derived class B.  I have purposefully left out the Shadows keyword in Class C to show that VisualBasic.NET implicitly Shadows any properties/methods in the derived class if the name matches the name of a property/method in the base class.
 
Now, here is a quick code snippet for a console app that will demonstrate this nuisance of Shadowing.
 

Sub Main() Dim cClass As New C Console.WriteLine("Typed as C: FirstName {0}, Lastname {1}", cClass.FirstName, cClass.Lastname) 'Typed as C: FirstName C, Lastname 3 Console.WriteLine("Typed as B: FirstName {0}, Lastname {1}", CType(cClass, B).FirstName, _
  CType(cClass, B).Lastname) 'Typed as B: FirstName B, Lastname 3 Console.WriteLine("Typed as A: FirstName {0}, Lastname {1}", CType(cClass, A).FirstName, _
CType(cClass, A).Lastname) 'Typed as A: FirstName A, Lastname 3 Console.ReadKey() End Sub

 

 

 

 

 

 

Notice how the value that is returned for Firstname is the value corresponding to the type by which my object is being accessed.  This correlates to my Silverlight example.  When I was adding items to my custom object programatically I was referencing it as the same type of which it is.  However, when the Silverlight run time was building the UIElement tree it was accessing my item as its base type so the items were added to the base type property, not my custom Shadows property.

So, when it comes to Shadowing, you will want to be aware that referencing your classes as the base type will expose the base types functionality and not the Shadowed functionality.

Fortunately Overrides works differently so that the functionality declared as Overrides on the most derived class will always be run and not the functionality of the base class(es). To verify this try removing the Overrides keyword from Class C.  Now the functionality that is declared as Overrides in Class B will always be accessed for the Lastname property.  You should get the following output to your console.

Typed as C: FirstName C, Lastname 3
Typed as B: FirstName B, Lastname 2
Typed as A: FirstName A, Lastname 2

 

Hopefully you have found this quick excursion into the finer points of Shadowing helpful and the next time you use Shadows you’ll know what to expect from your derived classes.

Tags: ,

Mar 12 2009

Focus on LOB’s in Silverlight 3

Category: .NET | Silverlight | Silverlight 3David @ 10:07

I know there are developers out there looking at Silverlight thinking that it’s just another media delivery platform and that Microsoft is just trying to gain market share over Adobe in this area. However, the truth, I am convinced, is much different.  The overlooked aspect of Silverlight that will make the biggest impact in the Rich Internet Application space is the support for Line-of-Business applications to be developed in Silverlight.

This past Monday The Knowledge Chamber posted an interview with Brad Abrams on Channel 9 in which Brad gives us a few teasers about the LOB support being added to Silverlight 3.0.  In the interview Brad shows us the new project template for a Silverlight project that gives a default design to your Silverlight application and that design will apparently be swappable for other default designs. There is also a short preview of new datagrid features and a new details view control.  He also highlights the new “Deep Link” feature that allows you to access specific places in your Silverlight application via a URI.  The only down part is that we have to wait until MIX09 to see the full feature set, but luckily that’s only another week!

Tags: , ,