Deze post is geïmporteerd van de oude blog en is nog niet geconverteerd naar de nieuwe syntax.
Yesterday I got invited by Microsoft France to Paris, to the Wax Club, to see the French Visual Gaming Finals.

My team mate, ZogStriP, participated in the High School competition there, so it was very exiting!

It was also a very good experience to learn French ;) And to get to know Paris, where the people are really crazy in traffic. Apparently, stop signs are just for decoration... Green or red, it all means the same :p

They played the games before and played the replay files on big screen, which were also recorded by a french television station. The station is on satellite and is called GameOne, I don't know yet when they will broadcast it. I'll have to find someone who can digitally record it, because they interviewed me as well :p

So, the High School competition: there were 2 pools, one with 3 games and one with 6. Our best competitor was Z² who lost with a very little difference each time.

In the end, our dll won the High School competition! Resulting in a PDA for my team mate (I'm too old for High School ;p).

But here is where something special happened, he gave me the PDA!

He recently became MVS in France and just received one as well. Isn't it a nice gesture? Microsoft France made a very good choice making him MVS, he really deserves it with this kind of attitude, a real teamplayer. (So, for all French companies reading my blog, go to his blog and check it out, he would be a great asset for your company!)

After this, it was time for the Open Division.

There, our bot had a hard time. We lost the quarter finals by 1 point, due to a bug causing the AI to stop :/ So, chances for 1st and 2nd were gone. Finally we ended up at the fourth place, because the same bug occured again in the next game, which is really a shame.

One thing is sure, being 4th already is good, especially in France, the country of Visual Gaming, now we only have to fix this bug :p Result of ending on 4th place: A fingerprint reader and I also got interviewed, in English :p This is really a nice example of "dissolving boundaries" :)


And to finish, here's a picture of ZogStriP and me (ZogStriP right, me left):



To ZogStriP: Thanks!
 
Deze post is geïmporteerd van de oude blog en is nog niet geconverteerd naar de nieuwe syntax.
When developing an application it’s possible to use debug mode to figure out why something is wrong, but when it’s time to deploy the application something else has to be integrated. To solution to this is logging. Implementing good logging functionality will make the Operations people who have to deploy your application happy as well, because they can integrate it into existing monitoring systems.

Enterprise Library was used to implement a flexible logging solution. Thanks to the Logging and Instrumentation Application Block it’s possible to integrate logging into your code, but decide where to output the log externally from the application. This way it’s possible to log to a flat file, a database, an email address, the event log, a message queue, WMI and custom implementations, without having to change code.

A Logging project was added to start, to provide some helper constants:

[csharp]
using System;

namespace MediaService.Logging {
public struct Priority {
public const Int32 Lowest = 0;
public const Int32 Low = 1;
public const Int32 Normal = 2;
public const Int32 High = 3;
public const Int32 Highest = 4;
} /* Priority */

public struct Category {
public const String Player = "Player";
public const String Remoting = "Remoting";
public const String Data = "Data";
public const String SqlServer = "SqlServerData";
} /* Category */
} /* MediaService.Logging */
[/csharp]

After this, a reference to the Logging project was added together with a reference to Microsoft.Practices.EnterpriseLibrary.Logging. A reference to the Enterprise Library Configuration Application Block was needed as well.

At this point it was possible to log messages by using the following construct:

[csharp]
if (randomSong == null) {
Logger.Write("Unable to select a random song.", Category.Player,
Priority.High, 1, Severity.Error);
} else {
Logger.Write(String.Format("Fetched song: {0} (Random).", randomSong.Path),
Category.Player, Priority.Low, 1, Severity.Information);
}
[/csharp]

Similar code had been added throughout the code to provide meaningful feedback. The only thing left was configuring where the log output had to go.

Using the Enterprise Library Configuration tool, an existing App.config was loaded and the Logging and Instrumentation Application Block was added. Under Client Settings, LoggingEnabled was to True.

A new category had to be added, called Player, by right clicking on Categories and selecting New – Category. This is the name that was used in the code to specify which log the output belongs to. It was possible to define multiple categories.

To define where the output had to go to, a new sink was added, called Player Flat File Sink, by right clicking on Sinks and selecting New – Flat File Sink. Player.log was chosen as a filename, without a header.

Formatters are used to define how a single log entry had to look. By default a Text Formatter was provided, which included extensive information. To have an overview log file, a new formatter was added by right clicking Formatters and selecting New – Text Formatter. The template for this Simple Text Formatter was the following:

[code]
{severity}
[{timestamp}]: {message}
[/code]

Finally a new destination was added by right clicking the Player category and selecting New – Destination. This destination was configured to use the Simple Text Formatter together with the Player Flat File Sink.



After this, the loggingconfiguration.config and loggingdistributorconfiguration.config files had to be copied in the Post-build event as well. At this point, the application had implemented a flexible logging strategy, where an administrator could easily decide to turn logging on or off and where the log output had to go to and which template had to be used.
 
Deze post is geïmporteerd van de oude blog en is nog niet geconverteerd naar de nieuwe syntax.
To configure the solution, Enterprise Library was used. This contained a Configuration Application Block which allowed defining various configuration sources externally from the application. This approach gave to ability to switch from XML configuration files to a database without having to change anything in the code. Because of this, it was also possible to distribute the application, and let an administrator choose where it should read the configuration from. An additional advantage of using the application block was the ability to automatically detect when the configuration had changed and retrieve the new values.

The easiest way to implement configuration, was to create a new project which contained all the possible configuration sections in the solution. Each configuration section was defined by a different class.

For example, to make the port used by Remoting in the application configurable, I created a class which contained this value, together with a public property for it. This class uses the Xml namespace, because it was serialized to XML, and the application block uses the public properties to populate the configuration data.

A default constructor also had to be present for XML Serialization.

The configuration data for the player was for example contained in the PlayerData class, which looked like this:

[csharp]
using System;
using System.Xml.Serialization;

namespace MediaService.Configuration {
public class PlayerData {
private Int32 remotingPort;

[XmlElement("RemotingPort")]
public Int32 RemotingPort {
get { return this.remotingPort; }
set { this.remotingPort = value; }
} /* RemotingPort */

public PlayerData() { }

public PlayerData(Int32 remotingPort) {
this.remotingPort = remotingPort;
} /* PlayerData */
} /* PlayerData */
} /* MediaService.Configuration */
[/csharp]

To use these values, a reference to the Configuration project had to be added, together with a reference to Microsoft.Practices.EnterpriseLibrary.Configuration. After this the configuration could be loaded with the following code:

[csharp]
using Microsoft.Practices.EnterpriseLibrary.Configuration;

namespace MediaService.Player {
public class PlayerService : System.ServiceProcess.ServiceBase {
private PlayerData configData = null;

private void LoadConfiguration() {
ConfigurationManager.ClearSingletonSectionCache("playerConfiguration");
try {
this.configData = ConfigurationManager.
GetConfiguration("playerConfiguration") as PlayerData;
} catch (Exception ex) {
this.configData = new PlayerData(4000);
}
[/csharp]

And to receive notifications the following code had to be added:

[csharp]
protected override void OnStart(string[] args) {
ConfigurationManager.ConfigurationChanged += new
ConfigurationChangedEventHandler(ConfigurationManager_ConfigurationChanged);
} /* OnStart */

private void ConfigurationManager_ConfigurationChanged(object sender,
ConfigurationChangedEventArgs e) {
this.LoadConfiguration();
// Check new values and perform possible actions
} /* ConfigurationManager_ConfigurationChanged */
[/csharp]

At this point, all code needed for configuration was done. Now the Enterprise Library Configuration tool had to be used to configure the application’s configuration source.

First, a new application had to be defined by using File – New Application. Then the Configuration Application Block had to be added through Action – New - Configuration Application Block. After this, a new configuration section was added by right clicking on the new application block and selecting New – Configuration Section.

This new section was called playerConfiguration, as it is in the code, and uses an XML Storage Provider and an Xml Serializer Transformer, both added by right clicking the new section and selecting them from the New menu.

The only thing that still had to be changed was the XML Storage Provider, playerConfiguration.config had to be given as a FileName. After this, the configuration had to be saved.



The XML file used for configuration was the following:

[xml]



xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4000



[/xml]

The only thing left to make sure the application loaded the configuration during testing, was to provide a Post-build event that copied the configuration file. To do this, in the project’s properties, under the Common Properties was a Build Events menu, where it was possible to define the Post-build event. The following had to be used to copy the playerconfiguration.config file:

[code]
copy "$(ProjectDir)playerconfiguration.config" "$(TargetDir)" >Nul
[/code]

When the application was started, it would call the LoadConfiguration method, which would populate the PlayerData class and provide all configuration settings of the application. If the configuration file would be changed when the application was running, the ConfigurationChanged event would be raised and the new configuration would be used.
 
Deze post is geïmporteerd van de oude blog en is nog niet geconverteerd naar de nieuwe syntax.
After everything was done on the server-side of the Remoting implementation, inside the Windows Service, it was time to add the consumer side. In the case of this project, the consumer was an ASP.NET Webservice running on the same machine.

This required little effort. First, System.Runtime.Remoting had to be referenced, together with the assembly containing the interface used for the controller object. After this it was possible retrieve the controller object with the following code:

[csharp]
private IPlayerServiceController GetPlayerServiceController() {
return (IPlayerServiceController)Activator.GetObject(
typeof(IPlayerServiceController),
String.Format("tcp://{0}:{1}/MediaServicePlayerController",
this.configData.RemotingHost,
this.configData.RemotingPort));
} /* GetPlayerServiceController */
[/csharp]

In this solution, the webservice does not need to reference the assembly containing the real controller, but only an assembly that contains the interface. The real implementation is running on the server-side, as an instantiated, marshalled object.

When the instance got returned, it was possible to use it very simple, like this code:

[csharp]
[WebMethod(Description="Stop playing the queue.")]
public void Stop() {
this.GetPlayerServiceController().StopPlaying();
} /* Stop */
[/csharp]
 
Deze post is geïmporteerd van de oude blog en is nog niet geconverteerd naar de nieuwe syntax.
When the Windows Service was successfully running, a way had to be found to control it. There was a ServiceController class which allowed controlling a service and sending messages to it trough the ExecuteCommand method. This method was limited to sending integers without getting anything back. A better solution was to use Remoting to control the service.

Remoting allows for interproces communication, making objects available between different processes. An object is passed from server to client by reference, where the client can work with it as if it was a real object at the client. Remoting takes care of collecting information about the client calls and sending it to the server, where it is passed to the server object which performs the action on the client’s behalf. The result of this operation is then sent back to the client.

Remoting can transport this information over different channels, such as TCP and HTTP for example. In the project, a TCP channel was used, with the following code:

[csharp]
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace MediaService.Player {
public class PlayerService : System.ServiceProcess.ServiceBase {
private TcpChannel tcpChannel;

private void SetupRemoting() {
this.tcpChannel = new TcpChannel(this.configData.RemotingPort);
ChannelServices.RegisterChannel(this.tcpChannel);
RemotingConfiguration.ApplicationName = "MediaServicePlayer";
[/csharp]


After a channel had been setup, there were different possibilities to make a certain object available. But first, the object had to be created. This was a simple class, which inherited from MarshalByRefObject, and implemented a custom interface.

[csharp]
using System;
namespace MediaService.Player {
public class PlayerServiceController: MarshalByRefObject,
IPlayerServiceController {
[/csharp]

The interface was used, to make it possible to only make the assembly with the interface available to consumers of the remote object, instead of the implementation.

After an object was created, it was possible to register this type as a WellKnowType. There were two possibilities for this. It could be registered as a Singleton, which would make sure only instance of the object lived on the server at a given time. The other possibility was to register it as SingleCall, which would create a new object for each call. None of these two proved to be successful, because they both were unable to call methods from the service. The solution was to instantiate a new object when the service started, and to make this instance remotely available. This allowed the object to be in contact with the Windows Service, making it possible to control it. The following code published the object on tcp://host:port/MediaServicePlayerController:

[csharp]
RemotingServices.Marshal(this.playerController,
"MediaServicePlayerController");
[/csharp]

At the end, when the service was stopped, everything had to be cleaned up. The published object got disconnected and the channel got unregistered.

[csharp]
private void TearDownRemoting() {
RemotingServices.Disconnect(this.playerController);
ChannelServices.UnregisterChannel(this.tcpChannel);
} /* TearDownRemoting */
[/csharp]