OpenLightGroup Blog

rss

Blogs from OpenLightGroup.net


C# is better! Well at least for project linking and complier directives for attributes.

So I have been one of a dwindling number of VB.Net advocates since I moved from Classic ASP (or  in other words shortly after the dinosaurs went extinct and the wheel was invented). However, today was the first time I had to use C# because I simply could handle how I had to code the VB. Don’t get me wrong I am actually language agnostic and truly believe that any .Net developer worth their salt should be able to code in either C# or VB. I use C# for a few projects, but usually default to VB for production application because it is my “native” language. I figured I should preface this article with these statements in hopes of preventing the typical language wars that ensue when topics like this are addressed. Now to the point.

I have recently started an application for my employer (Washington University School of Medicine – Pediatrics Department) that would be built in Silverlight 3. It all began as every other project I have built for them, and then things took a nasty turn. I had created a set of DTOs to be used in the bottom ASP.Net layers to map the entity objects to Serializable objects to be exposed via ASMX web services. This all worked fine, until I began to bind them to the DataGrid and DataForm controls. It quickly occurred to me that I need to add Data Annotations to the properties to control the UI functionality. However, since I was using ASMX services the objects were actually recreated in the auto generated proxy code for the Silverlight project.

Great, now what?!? If I edit this code and add the attributes I need it will be overwritten. I thought about creating two sets of DTOs, one for ASP.Net and one for Silverlight. This would allow me to use the attributes Silverlight needs. Hmm, that is starting to smell. Going a step further, that means I would have to map the data object to the ASP.Net DTOs and then map the proxy objects to the Silverlight DTOs. Alright that is just rancid, there is no way I am doing that!!!

Then I remembered a neat little tool called Project Linker I had seen at TechEd earlier this year. So off I went to download and install this handy add-in. No problem, it installed just fine and after a restart of visual studio I was able to create a Silverlight class library and link a standard Class Library to it. Perfect, now I am getting somewhere, but wait, not so fast! The DataAnnotations are only available in Silverlight projects so I will need to use a compiler directive to instruct the compiler to ignore these attributes in the standard class library project. This should be no problem right, I mean what’s the big deal just put a # before your if statement and viola!

#If SILVERLIGHT Then
    <System.ComponentModel.DataAnnotations.Display(Name:="First Name")> _
#End If
    Public Property FirstName() As String
        Get
            Return _firstName
        End Get
        Set(ByVal value As String)
            _firstName = value
        End Set
    End Property

Umm, nice try but what about the line continuation!?! This will give you the dreaded blue squiggles and messages stating “#If' block must end with a matching '#End If'.”  and “Attribute specifier is not a complete statement. Use a line continuation to apply the attribute to the following statement.” So I shuffled things around a bit and came up with this:

Public Class Person
    Private _firstName As String
#If SILVERLIGHT Then
    <System.ComponentModel.DataAnnotations.Display(Name:="First Name")> _
    Public Property FirstName() As String
#Else
    Public Property FirstName() As String
#End If
        Get
            Return _firstName
        End Get
        Set(ByVal value As String)
            _firstName = value
        End Set
    End Property
End Class

Well this works, but again the solution is starting to smell. The readability of this code just plummeted and who really wants to define the property twice?!? Nope, I am too Type A for this solution. So being completely frustrated at this point I had to walk away for a bit to clear my mind and wait for the "eureka” moment to hit. After a few minutes, it did! Use C# it should work without having to duplicate your property definitions! I went back and sat down to try it out and this is what I came up with:

using System;
using System.Net;
#if SILVERLIGHT
using System.ComponentModel.DataAnnotations;
#endif
namespace Common
{
    public class Person
    {
#if SILVERLIGHT
        [Display(Name="First Name")]
#endif
        public string FirstName { get; set; }
    }
}

Are you kidding me!?!?! Seriously, that is so much better than the VB solution! My property is now one line long, the attribute is enclosed in the compiler directive and life is good!

Now I am not saying that I am switching to coding everything in C#, but I am saying that if you are wanting to share code between Silverlight and standard .Net libraries C# is a must. Thanks to the goodness of .Net I was able to keep all of my other code as-is in VB, and simply extract all of my DTOs into the linked C# libraries. Once, I got over this hurdle the refactor took less than an hour to convert all of the reference and recreate all of the DTOs in C#.

One last gotcha, I could not get Visual Studio to “Reuse types in all referenced assemblies” while consuming ASMX web services. I also had to convert my web services to Silverlight enabled WCF services before the generated proxy would actually use the DTO from the Silverlight library. I did not spend much time trying to figure this out and see if there was a work around. In this case, it really made little difference to me if the service was ASMX or WCF. Just thought I would drop that nugget into the article while I was at it.

I hope this helps, happy translating!





Comments are closed.
Showing 6 Comments
Avatar  TWAIN lover 8 years ago

Thank you. I need to learn more about C#. :)

Avatar  Ian T. Lackey 8 years ago

Well I tested referencing a VB Silverlight Class Library from a Non-Silverlight application and I get no errors but the object defined in the silverlight project does not show up at all. Very strange behavior... I may look into this more, but for now. I will stick with Greg's solution and use a C# SL library and reference it from the Silverlight and Non-Silverlight applications \ libraries. So I guess C# wins this hands down!

Avatar  Ian T. Lackey 8 years ago

Michael, &lt;br&gt;I thought you would like this post. :P

Avatar  Ian T. Lackey 8 years ago

Greg, well goes to show how little I use C#. ;) I had tried this in VB.Net with version 2 and it did not appear to work (as you had menetioned). I will try it out with version 3 when I get a chance and report back the findings.&lt;br&gt;&lt;br&gt;Thanks very much for your input, it was very helpful!

Avatar  Greg Levenhagen 8 years ago

To share a class library between a Web and a Silverlight project, you can use a Silverlight class library if you're using C#. If you're using VB.NET, the compiler complains about the versions. That was definitely the case in Silverlight 2. In Silverlight 3 it still works for C#, but I have not tested if VB.NET still complains.&lt;br&gt;&lt;br&gt;This means, you can have a Silverlight Application, Web Application and Silverlight Class Library within your solution. Put your DTOs in the class library and reference that class library in the two other projects.

Avatar  Michael Washington 8 years ago

One more reason to use C# (with Silverlight at least) it is much easier to copy and paste code examples from the web because most are in C# :)