Skip to content

Iloggable

Sharing code between Silverlight and .NET

Currently, a Silverlight Class Library cannot be loaded by the server side project and vice versa. This despite there being very close parity in the BCL on either side. Now, I agree that sharing actual business logic between client and server is a bit of an edge case, but when it comes to data interchange, having a single codebase for you DTOs would be very useful.

Luckily, with a bit of trickery, this can be accomplished, although it would be nice if Visual Studio could just do this for you. I've done this on two different projects, once creating DTOs that were then serialized using the JSON DataContract serializer and other other time using the normal XmlSerializer.

The basic trick is this: Two separate projects can point at the same source code files (and even the integrated source control providers will play along with this game). However, playing by Visual studio rules you can't just create two projects in the same directory because the wizards treats ProjectName == DirectoryName. Here's how you get around this:

  1. Create a new server side Class Library, say Server.Dto.
  2. Create a new Silverlight Class Library, say Silverlight.Dto.
  3. Clean out that default Class.cs and update both to have the same default namespace Foo.Dto. Your solution should look something like this:
  4. Now, right-click on Silverlight.Dto and choose Remove
  5. Close Visual Studio
  6. Rename the Silverlight.Dto/Properties directory to Silverlight.Dto/Silverlight.Properties
  7. Copy Silverlight.Properties and Silverlight.Dto.csproj to the Server.Dto directory
  8. Now, and this is the tricky bit, open Silverlight.Dto.csproj in some text-editor (notepad works, but don't try to use Visual studio for this) and change the line

<Compile Include="Properties\\AssemblyInfo.cs" />
to
<Compile Include="Silverlight.Properties\\AssemblyInfo.cs" />

  1. Re-open your solution, right-click on the Solution in the Solution Explorer and choose Add -> Existing Project..., browse to Server.Dto and select Silverlight.Dto.csproj
  2. Add your first shared class FooDto.cs to Server.Dto (if you add it on the Silverlight side, you need to clean up a bunch of using statements).
  3. Select Silverlight.Dto and click the Show All Files button at the top of the panel. You should see FooDto.cs in Silverlight.Dto now
  4. Right-click FooDto.cs and choose Include in Project, like this:
  5. Voila, you now have two assemblies referencing the same code so that you can use the same code on both client and server sides. Just repeat the last couple of steps for every new class you want to share.

I know you could use a Web Service from within Silverlight and would automatically generate you the proxy on the client side. And I'd recommend that if your payload is dynamic. However, if your payload is generated occasionally by a server side program or periodic service, this methods lets you create Dto's, serialized in your favorite manner that can be consumed as static files with WebClient.

Epoch DateTime conversion Extension Methods

Interop with unix often requires dealing with Epoch or Unix time, or the number of seconds since January 1st, 1970 UTC. And if you throw java in the mix, then epoch becomes milliseconds, since they define System.currentTimeMillis() as the number _milli_seconds since the Epoch. Anyway, i figured, this was the perfect use of Extension methods. Well, almost... There's still the issue that getting a DateTime object from seconds requires a static method added to DateTime, which extension methods do not currently support. This means that instead of

DateTime utcDateTime = DateTime.FromEpochSeconds(seconds)

we have to be content with

DateTime utcDateTime = DateTimeEx.FromEpochSeconds(seconds)

Now i also added extensions on long and int but, really, that falls into the realm of stupid extension method tricks. I left them in there, only because they are part of DateTimeEx, therefore will only be available if the appropriate namespace is included and so is at least tangentially relevant in the current scope. Well, that's my rationalization, at least. With this extra extension method you now can do

DateTime utcDateTime = 1205003848.DateTimeFromEpochSeconds();

The one thing to be aware of with all these helpers is that it always deals with UTC time, i.e. the DateTime that you convert to epoch time needs to have a DateTimeKind that is not Unspecified. Conversely, the DateTime you get back is UTC and if you want to deal with it with localtime, you need to call ToLocalTime() on it first.

Anyway, here's the class:

using System;

namespace Droog.DateTime
{
  public static class DateTimeEx
  {
    public static DateTime FromEpochMilliseconds(long milliseconds)
    {
      return new DateTime(1970, 1, 1,0,0,0,DateTimeKind.Utc).AddMilliseconds(milliseconds);
    }

    public static DateTime FromEpochSeconds(int seconds)
    {
      return FromEpochMilliseconds((long)seconds \* 1000);
    }

    public static DateTime DateTimeFromEpochMilliSeconds(this long milliseconds)
    {
      return FromEpochMilliseconds(milliseconds);
    }

    public static DateTime DateTimeFromEpochSeconds(this int seconds)
    {
      return FromEpochSeconds(seconds);
    }

    public static int ToEpochSeconds(this DateTime dt)
    {
      return (int)(ToEpochMilliseconds(dt)/1000);
    }

    public static long ToEpochMilliseconds(this DateTime dt)
    {
      return (long)(dt.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalMilliseconds;
    }
  }
}

Synergy

I used to run x2vnc and win2vnc back in the MP3 days to let me control my Windows and linux boxen. Later I used the same setup with my old MacBook 15" and a Linux box. The other day, my friend n8 posted about his Synergy setup, which came perfectly timed. I just started a new gig at Bunkspeed and I'm using a dedicated desktop for dev instead of my MacBook Pro, but i don't want my Mac to be wasted. So i set up Synergy on both my home and work desktops and have the Mac on a stand running two Synergy clients (only one of which ever finds a server to connect to. This setup rules!

Update: Don't know if this is something i'll find a way around, but apparently logging on to the VPN killed the connectivity between my desktop and mac :(

Update 2: Ok, as simple as going into the Advanced config and telling it what local IP to listen for connections on. All good again

VS2k5 & WPF

After having tried a bunch of different iterations to get the WPF tools installed for VS2k5, here's what finally worked"

  • Install .NET 3.0
  • Install Visual Studio Tools for WCF/WPF
  • And only then install .NET 3.0 SP1

Talk about annoying dependencies.

Addicted to .Net 3.5

Outside of LINQ, i thought that 3.5 was a lot of cool but not vital syntactic sugar. This weekend marks the first time since November that I fired up VS.NET 2k5 to build an app targeting the 2.0 framework and I was amazed how much I'd already come to rely on that sugar. Now this might be seen as an invalidation of my preference of explicit, verbose syntax versus the terse syntax of many scripting languages. I'd like to point out that terseness and expressiveness in sytnax are two separate things. Syntactic sugar that let's me express my action in more concise code that easily conveys the meaning is not the same thing as using a terse vocabulary to keep the typing down and requiring memorization of abbreviated keywords to understand the code. Anyway, here are the parts of 3.5 I've missed more than once this weekend.

Extension Methods on IEnumerable

The plethora of extension methods on all things IEnumerable is largely due to LINQ, but the To* methods have become just a basic part of my vocubulary. Taking the Values of a Dictionary into an Array of the same type now is seems just painfully verbose without the ToArray() method. Compare

FileInfo[] f = new FileInfo[files.Count]; files.Values.CopyTo(f,0); return f;

with

return files.Values.ToArray();

Object/List initializer syntax

Now this I really thought of as frivolous. However, using objects that use DTOs as their initializer/storage, initialization does become rather awkward without loops or long constructors:

FileInfoData[] remoteFileData = new FileInfoData[]
{
  new FileInfoData(),
  new FileInfoData(),
  new FileInfoData()
};
remoteFileData[0].name = "test1.mpg";
remoteFileData[1].name = "test2.mpg";
remoteFileData[2].name = "test10.mpg";
FileInfo[] remoteFiles = new FileInfo[]
{
  new FileInfo(remoteFileData[0]),
  new FileInfo(remoteFileData[1]),
  new FileInfo(remoteFileData[2]),
};
versus

FileInfo[] remoteFiles = new FileInfo[]
{
  new FileInfo(new FileInfoData()
  {
    Name = "test1.mpg"
  }),
  new FileInfo(new FileInfoData()
  {
    Name = "test2.mpg"
  }),
  new FileInfo(new FileInfoData()
  {
    Name = "test10.mpg"
  }),
};

Anonymous delegates are a pain and hard to read

I needed to pass in a delegate to a function as a factory callback. Perfect scenario for a nice concise lambda. But I was in 2.0, so that meant defining a delegate and anonymous delegate syntax resulting ing

public delegate ILocalFileSystemManager LocalCreateDelegate(string localPath, string extension);

public class FileSystemManagerFactory
{
  public FileSystemManagerFactory( LocalCreateDelegate localFactory )
  {
    this.localFactory = localFactory;
  }
}

FileSystemManagerFactory factory = new FileSystemManagerFactory(
  delegate(string localPath, string extension)
  {
    return new MockLocalFileSystemManager(localPath, extension);
  });
instead of

public FileSystemManagerFactory( Func<string,string,ILocalFileSystemManager> localFactory )
{
  this.localFactory = localFactory;
}

FileSystemManagerFactory factory = new FileSystemManagerFactory(
  (localPath, extension)
  =>
  return new MockLocalFileSystemManager(localPath, extension);
  );

Automatic Properties

If there is one feature of C# (well and java as well) that is the most code generated, it's getters and setters. I've never liked how code generation tools created those for me, since i liked having my private members in one place and Properties in another. So i've been typing them out for years. But with C# 3.0, we got automatic properties. The two patterns, read/write properties and read-only properties are oft repeated like this

string readwriteMember;
string readonlyMember;

public string ReadWrite
{
  get { return readwriteMember; }
  set { readwriteMember = value; }
}

public string ReadOnly { get { return readonlyMember; }

Not a ton of code, but certainly takes more time to write than

public string ReadWrite { get; set; }

public string ReadOnly { get; private set; }

Ho hum.. I'm in 2.0, so i'll have to deal, but I certainly hope that 3.5 has a fast pick-up rate on the client (on the server, I can still control my environment).

LINQ: Immutability vs. Deferred execution

The last couple of nights I've been playing with some Linq to Sql and a whole lot of Linq to Objects and I have to say where coming up with complex Regular Expressions used to be one of my favorite puzzles, coming up with complex projections and transformations through Linq is quickly taking its place. Simple Linq is well documented, but when it comes to aggregation, it's a lot sparser. I expect to write more of that up once I feel more comfortable with the syntax.

In the meantime, I wanted to write up some non-obvious observation about deferred execution with Linq. Considering the gotchas with lambdas, it's easy to extend the lessons learned to linq, since it is after all deferred execution. But what's different with Linq is that, while execution is deferred, the expression tree built via a query is also immutable. I came across this trying to do some simple query re-use.

Let's start with a simple DTO:

public class Order
{
  public Order(int id, int val, bool buyOrder)
  {
    Id = id;
    Value = val;
    IsBuyOrder = buyOrder;
  }
  public int Id { get; set; }
  public int Value { get; set; }
  public bool IsBuyOrder { get; set; }
}

And a set of this data:

Order[] orders = new Order[]
{
  new Order(1,2,true),
  new Order(2,2,false),
  new Order(3,4,true),
  new Order(4,4,false),
  new Order(5,6,true),
  new Order(6,6,false),
};

Let's split those into buy and sell orders:

var buyOrders = from order in orders
          where order.IsBuyOrder
          select order;

var sellOrders = from order in orders
                 where !order.IsBuyOrder
                 select order;

If we want to find the buy and the sell order with a value of 2, you'd think we could write one query and re-use it for both of those queries. Since both queries results in IEnumerable, how about we define a query source and assign the value of either above query.

IEnumerable<Order> orders2 = null;

var orderAtTwo = from order in orders2
                 where order.Value == 2
                 select order;

orders2 = buyOrders;
int buyOrderId = orderAtTwo.First().Id;

orders2 = sellOrders;
int sellOrderId = orderAtTwo.First().Id;

Console.WriteLine("buy Id: {0}, sell Id: {1}", buyOrderId, sellOrderId);

Since the query is deferred until we call .First() on it, that seems like a reasonable syntax. Except this will result in an System.ArgumentNullException because our query grabbed a reference to orders2 at query definition, even though the query won't be executed until later. Giving orders2 a new value does not change the original reference in the immutable expression tree.

A way around this is to replace the actual contents of orders2. However, for us to do that, we have to turn it into the query source into a collection first.

orders2.Clear();
orders2.AddRange(buyOrders);
int buyOrderId = orderAtTwo.First().Id;

orders2.Clear();
orders2.AddRange(sellOrders);
int sellOrderId = orderAtTwo.First().Id;

Console.WriteLine("buy Id: {0}, sell Id: {1}", buyOrderId, sellOrderId);

This gives us the expected

buy Id: 1, sell Id: 2

Let's put aside the awkwardness of clearing out a list and stuffing data back in, this code has another unfortunate sideeffect. .AddRange() actually executes the query passed to it, so we execute our buy and sell queries to populate orders2 and then execute orderAtTwo twice against those collections. The beauty of linq is that if you create a query from a query, your not running multiple queries, but building a more complex query to be executed. So, what we really want is query "re-use" that results in single expression trees at execution time.

To achieve this, we need to move the shared query into a separate method such as:

private IEnumerable<Order> GetTwo(IEnumerable<Order> source)
{
  return from order in source
         where order.Value == 2
         select order;
}

and the code becomes:

int buyOrderId = GetTwo(buyOrders).First().Id;
int sellOrderId = GetTwo(sellOrders).First().Id;

Console.WriteLine("buy Id: {0}, sell Id: {1}", buyOrderId, sellOrderId);

This gives the same output as above, and we're only running two queries, each against the original collection. The method call means that we don't get to re-use an expression tree, since it builds a new one, combining the expression tree passed to it with the one it builds itself.

Struct's via Automatic Properties can be tricky

Here's a bit of code i just got through debugging...

public Point Point { get; private set; }

public void Offset(Point origin)
{
  Point.Offset(-origin.X, -origin.Y);
}

Can you tell what's wrong here? Let's just say that the Offset won't take.

structs are value types, which means anytime you pass one around you get a new copy. So far so good. And that means when you expose a struct value via a property, the accessing party always is looking at a copy. Again, fine, after all when you do a set you change the stored value and if you need to manipulate it, you just manipulate the actual struct.

Enter Automatic properties and you might forget about this last detail and not realize that you never get access to the underlying value, even from within the class. I.e. when I call Point.Offset, i'm calling it on the copy that was passed to me and the resulting value is immediately thrown away. So i just went back to using the property to facade a private Point, which i can now manipulate inside of Offset. Duh.

More Deferred Execution Fun: foreach and delegation scope

This is closely related to my last post on deferred execution gotchas and its basically more "if you inline delegated code, you may easily overlook scope side-effects". This time it's about dealing with foreach and using the local each item for deferred execution.

public void SpawnActions()
{
  foreach (ActionContext context in contexts)
  {
    int id = context.Id;
    Action<int> callback =  
      (workerNumber) =>
      {
        Console.WriteLine("{0} Id: {1}/{2}", workerNumber, id, context.Id);
      };
    ThreadPool.QueueUserWorkItem(new WaitCallback(FutureExecute), callback);
  }
}

public void FutureExecute(object state)
{
  int id = worker++;
  Action<int> callback = state as Action<int>;
  Thread.Sleep(500);
  callback(id);
}

The output looks like this:

0 Id: 0/9
1 Id: 1/9
2 Id: 2/9
3 Id: 3/9
4 Id: 4/9
5 Id: 5/9
6 Id: 6/9
7 Id: 7/9
8 Id: 8/9
9 Id: 9/9

So while the foreach scope variable context is kept alive for the deferred execution, it turns out that foreach re-uses the variable on each pass through the loop and therefore when the Action is later executed, each one has a reference to the last context. So what we need to do is create a true local variable for context so that the lambda's scope can hold on to the reference we want.

foreach (ActionContext context in contexts)
{
  int id = context.Id;
  // locally scoped variable
  ActionContext c2 = context;
  Action<int> callback =  
    (workerNumber) =>
    {
      Console.WriteLine("{0} Id: {1}/{2}", workerNumber, id, c2.Id);
    };
  ThreadPool.QueueUserWorkItem(new WaitCallback(FutureExecute), callback);
}

And now our results are a bit more what we expected:

0 Id: 0/0
1 Id: 1/1
2 Id: 2/2
3 Id: 3/3
4 Id: 4/4
5 Id: 5/5
6 Id: 6/6
7 Id: 7/7
8 Id: 8/8
9 Id: 9/9

Copying a Silverlight User Control from one project to another

Here's something I tracked down with no help from error messages:

When you copy a user control in Silverlight 1.1 from one project to another the Xaml that the control loads will have it's Build Action set to SilverlightPage. When you then run your project and try to create an instance of that control you'll get the ever so informative AG_E_INVALID_ARGUMENT. All you need to do to fix it, is set the Build Action to Embedded Resource again. Tada!

I love declarative definition of UI with behavior wired to static code. But man, at its current state, the debugging support for it just isn't there. I mean it's bad enough that having strings in the declarative side to link to actions that won't be updated by normal refactoring, nor will they show up as references, but at this state Xaml brings the worst part of scripting languages to compile-time checked coding:

Vague runtime errors without a stacktrace

Bah.