Using DevTracer with Microsoft® Silverlight™
Silverlight is a fairly new technology from Microsoft. It provides a cross
platform plugin for browsers for creating rich internet applications.
Silverlight 2 is currently in beta. Applications can be developed with .NET
languages like C# and Visual Basic® .NET. Silverlight has
its own version of the .NET framework, which is a small subset of the standard framework
to give it a small footprint what download size is concerned. It is called .NET Framework
Class Library for Silverlight.
Because the framework is a small subset of the standard framework, many classes
are missing. Unfortunately the class TraceListener is missing
as well. Therefore it is not possible to use DevTracer the
way it is possible with a Windows Forms or ASP.NET application.
The framework for Silverligth still contains a class
Debug in namespace
System.Diagnostics. But this class is limited; it outputs the trace
information to the output window of Visual Studio, and it does not use a TraceListener.
It also does not have methods
Indent(),
Unindent() and
Write(),
which are part of the Debug class in the full framework class library. And
class Trace is missing completely.
Therefore it is not possible to use
DevTracer Component with Silverlight. But because
DevTracer can be used with ASP.NET, there is still
a way to use it.
Normally you will use ASP.NET on the server when you develop a Silverlight
application, and the Silverlight plugin is hosted in an ASP.NET page.
The principle is fairly easy: send the trace information to a
Web Service build with ASP.NET, and this Web
Service then uses DevTracer Component to
send it to DevTracer Monitor. The steps to make it work
are:
Then you will be able to add tracing to your Silverlight application with
code like this:
NRTracer.WriteLine("Hello from Silverligth");
Step by Step
For this step by step guide we use Visual Studio 2008. Silverlight 2 beta
must be installed. It can be downloaded at the Silverlight site.
Create a new Silverlight project
Start Visual Studio 2008 and create a new Silverlight project

In the next dialog for adding a web site just take the defaults.

Add a button
Now the solution will be created with two projects: SilverlightDemoWeb for
the ASP.NET application and SilverlightDemo for the Silverlight
plugin. Initially the file Page.xaml is displayed,
which is basically empty (without any controls yet). Therefore just add a button
with an event handler for the click event. The xaml
code should look like this:
<UserControl x:Class="SilverlightDemo.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<Button x:Name="TestButton" Click="TestButton_Click" Width="100" Height="50" Content="Click
Me!" />
</Grid>
</UserContro>>
Add a Web Service to SilverlightDemoWeb
To add a Web Service, right click the project SilverlightDemoWeb and select Add
New Item ... The Add New Item dialog
is shown. Choose WCF Service, change the name to
DevTracerService.svc, and close the dialog using
the Add button.

Visual Studio adds the Web Service to the project,
and displays file IDevTracerService.cs with the
Service Contract. It already has a method DoWork(). Change this method to WriteLine(string
str). The file with the Service Contract should look like this now:
[ServiceContract]
public interface IDevTracerService
{
[OperationContract]
void WriteLine(string str);
}
The using statements have been omitted here. You
must also change file DevTracerService.cs. Replace
method DoWork() with WriteLine()
public class DevTracerService : IDevTracerService
{
public void WriteLine(string str)
{
System.Diagnostics.Debug.WriteLine(str);
}
}
Here we use the class Debug of the standard .NET
framework. Instead of calling Debug.WriteLine(),
it is possible to call Trace.WriteLine() alternatively.
The difference is: Debug.WriteLine() is only available
when building a debug version, Trace.WriteLine()
is also available in the release version.
Important:
Behind the scene Visual Studio does quite some work when creating the
Web Service. Part of the work it does is writing some configuration information
about the Web Service to WEB.CONFIG. Unfortunately
with the beta version of Silverlight 2 the Web Service
will not work with the information in WEB.CONFIG. You must make a change manually.
Load WEB.CONFIG and scroll to the bottom. There you will find the following lines:
<services>
<service behaviorConfiguration="DevTracerServiceBehavior" name="DevTracerService">
<endpoint address="" binding="wsHttpBinding" contract="IDevTracerService">
The binding must be changed from wsHttpBinding to basicHttpBinding
<services>
<service behaviorConfiguration="DevTracerServiceBehavior" name="DevTracerService">
<endpoint address="" binding="basicHttpBinding" contract="IDevTracerService">
Now we have to configure the Web Service to use
DevTracer Component. We choose to use the configuration file method and
add the following lines to WEB.CONFIG.
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="myListener"
type="NRSoftware.Tracer.Listener,NRSoftware.Tracer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=867dfab712f16c0b"
initializeData="localhost:12345" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
In these configuration settings please have a look at initializeData="localhost:12345".
12345 is the port number used, and
localhost specifies the ip address used to send trace information to
DevTracer Monitor (localhost corresponds to 127.0.0.1).
If you want to run DevTracer Monitor on a computer
different from the one running the Web Service,
you have to adjust this setting.
Now we are finished with project SilverlightDemoWeb.
Now we have to prepare the Silverlight plugin.
Add a Service Reference to SilverlightDemo project
To add the service reference, right click project SilverlightDemo
in solution explorer and select Add Service Reference
... . The Add Service Reference dialog
pops up, with basically all fields empty. Press the button
Discover, and the Web Service we created
before will be found. Select IDevTracerService on
the left, and change the name to DevTracerService
before proceeding with OK.

Now we only need the helper class to encapsulate the call to the Web Service.
Add wrapper class NRTracer
This is quite easy. Right click project SilverlightDemo
in solution explorer and select Add → Class...
. Enter NRTracer.cs as name. You get an empty class
skeleton, which needs to be filled with some life. Here is the completed class:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightDemo
{
public static class NRTracer
{
private static DevTracerService.DevTarcerServiceClient _client = null;
public static void WriteLine(string str)
{
if (_client == null)
_client = new SilverlightDemo.DevTracerService.DevTarcerServiceClient();
_client.WriteLineAsync(str);
}
}
}
That's all. Now your Silverlight application is ready to use DevTracer.
You just have to call
DevTracer.WriteLine("information ....");
and the information will be displayed.
In the first step Create a new Silverlight project
we added a button to page.xaml, including a click
event handler TestButton_Click. Let's fill this
event handler with some code. The event handler can be found in file
Page.xaml.cs
private void TestButton_Click(object sender, RoutedEventArgs e)
{
NRTracer.WriteLine("In Event Handler 'TestButton_Click' : Hello from Silverlight");
}
Now let's start DevTracer Monitor (ip address to listen
to should be localhost, the port
12345) and the Silverlight application (F5 in Visual Studio).
The browser will start, and display an empty page with the button created before.
Clicking the button then shows the message from the event handler in
DevTracer Monitor.

Some Remarks about this implemention
The sample code shown here only implements one method in class
NRTracer and the Web Service:
WriteLine(). Theoretically it would be possible to implement methods
like Write(), Indent()
and Unindent() as well. We did not do this for a
simple reason. With .NET for Silverlight you can
call a Web Service only asynchronously (that's why class DevTracer call the
method WriteLineAsync(), there is no method WriteLine()).
This has some consequences. Look at the following code snippet:
for (int line=1 ; line <=1000 ; line++)
{
NRTracer.WriteLine(string.format("This is line no. {0}.",line));
}
Running this code works, but looking closely at the data received by
DevTracer Monitor will reveal that sometimes the data do not appear in
the order expected.
This is caused by the asynchronous calls to the web service. But because there is
no guarantee that the data are received in the same order they were send, methods
like Write() or Indent()
do not make much sense.
With some effort it is possible to synchronize calls to the
Web Service. But it is not recommended.
In case it is required that data arrive in the Monitor in the correct order, we
recommend a different approach. For this case enhance class DevTracer
to cache trace information, and add a method which flushes the cached information
and sends them to the Web Service. The enhancement
could look like this:
private static StringBuilder _sb = null;
public void WriteLineToCache(string str)
{
if (_sb == null)
sb = new StringBuilder();
sb.AppendLine(str);
}
public void Flush()
{
if (_sb != null)
{
WriteLine(_sb.ToString());
_sb = null;
}
}
The sample with 1000 lines can then be rewritten:
for (int line=1 ; line < 1000 ; line++)
{
NRTracer.WriteLineToCache( string.format("This is line no. {0}.",line));
}
NRTracer.Flush();