Category Archives: C#

Singletons using C# 6 syntax

A while back I wrote the post The Singleton Pattern in C# and just thought it’d be nice to use C# 6 syntax to update this post.

So here’s the code with the change for to use default property syntax

public sealed class Singleton
{
public static Singleton Instance { get; } = new Singleton();

static Singleton() { }
private Singleton() { }
}

Where to store your application data?

Actually I don’t intend to answer the question “Where to store your application data?” because this will depend on your requirements, but what this post will look at is, some of the options available and hopefully help shed light on what best suits your application.

Application data can be separated into two types, user specific data and application specific data (or if you prefer “All User” data).

Obviously multiple user’s might have access to a single machine but an application may be available to all users of a machine, hence we need a way to store settings specific to each user on the machine, for example user preferences. However we also may have application specific data, maybe the application stores a list of URL’s specific, in essence global settings.

Let’s look at some of our options for storing data…

Within your application’s folder

Obviously we could simply store configuration data etc. along with the application, one way to locate this folder is, as follows

var folder = Path.GetDirectoryName(
   Assembly.GetExecutingAssembly().Location) +
   Path.DirectorySeparatorChar + 
   SettingsFileName;

Here we might store a file for application specific data then create another file using the username (here we can use the Environment.UserName) of the user logged into the machine for each user.

This is a simple solution and in some cases more than adequate, plus it has the benefit that if we delete the application (i.e. it wasn’t installed via an installer) then we delete any configuration files.

Program Data

The ProgramData folder is on the system drive and is hidden by default (see C:\ProgramData). As can be inferred from the name, it’s generally used for settings specific to the application itself, i.e. not based upon specific users on a machine.

We can access it using the following code

var folder = Path.Combine(
   Environment.GetFolderPath(
      Environment.SpecialFolder.CommonApplicationData),
      "YourAppName");

Interestingly you can access the ProgramData using C:\Users\AllUsers in File Explorer, although File Explorer will state that you are in C:\Users\AllUsers it’s the same folder as C:\ProgramData.

Program Data can also be located using the environment variable %programdata%.

User Data

So we’ve seen that we can use the Environment.UserName to combine with our file name to create user files, but Windows already has the capability locations for user data. Plus, depending how your OS is set up, this data may be used across any machine a user logs into (known as Roaming).

The default location for the following “User Data” folders is under the location C:\Users\<username>\AppData

Local

The Local folder can be located using the special folder LocalApplicationData, for example

var folder = Path.Combine(
   Environment.GetFolderPath(
      Environment.SpecialFolder.LocalApplicationData),
      "YourAppName");

and is also available via the environment variable %localappdata%.

This location contains data that cannot be stored in the Roaming folder, for example data that’s specific to the machine the user is logged into or that is too large to store in a synchronized roaming folder (i.e. where Roaming folders are synchronized with a server).

Roaming

As hinted at in the section on the Local folder. The Roaming folder can be synchronized with a server, i.e. this is a profile which is accessible from other machines that a user logs into on the same domain. Hence anything stored here will “follow” the user around and so is very useful for preferences, favourites etc. However the space available may be limited depending upon quota settings or other space limitations.

To access this folder we simply use the ApplicationData special folder or environment variable %appdata%, for example

var folder = Path.Combine(
   Environment.GetFolderPath(
      Environment.SpecialFolder.ApplicationData),
      "YourAppName");

LocalLow

The LocalLow folder is basically a restricted version of the Local folder. The data is not synchronized with a server and hence does not move from the machine its created on and it has a lower level of access.

When I say “restricted” or “lower level access” basically this means the application being run, itself has security constraints placed upon it.

The LocalLow folder does not have an entry within the SpecialFolder enumeration, so access the folder you need to use the following (copied from Thomans Levesque’s answer on StackOverflow – https://stackoverflow.com/questions/4494290/detect-the-location-of-appdata-locallow)

[DllImport("shell32.dll")]
static extern int SHGetKnownFolderPath(
   [MarshalAs(UnmanagedType.LPStruct)] Guid rfid, 
   uint dwFlags, 
   IntPtr hToken, 
   out IntPtr pszPath);

public static string GetFolderLocalLow()
{
   var pszPath = IntPtr.Zero;
   try
   {
      var hr = SHGetKnownFolderPath(folderGuid, 0, IntPtr.Zero, out pszPath);
      if (hr < 0)
      {
         throw Marshal.GetExceptionForHR(hr);
      }
      return Marshal.PtrToStringAuto(pszPath);
   }
   finally
   {
      if (pszPath != IntPtr.Zero)
      {
         Marshal.FreeCoTaskMem(pszPath);
      }
   }
}

Accessing location via the environment variables

In a few places I’ve shown the environment variable for each of the locations mentioned. We can also use these variables to locate the folders, for example

var location = 
   Environment.ExpandEnvironmentVariables("%AppData%")

This will result in returning the Roaming folder location, but what’s nice is this static method will work with environment variables combined with file locations (as you’d probably expect), so for example

var location = 
   Environment.ExpandEnvironmentVariables("%AppData%\MyApp")

This will return a path along the lines C:\Users\<username>\AppData\Roaming\MyApp

Source added to https://github.com/putridparrot/blog-projects/tree/master/FileLocations

More ASP.NET Core with C#

In the previous post I looked into the F# Giraffe library which makes writing all sorts of web request/response code pretty simple. This in turn is built on top of the existing functionality within ASP.NET Core.

Let’s again look at the bare bones code from running up Kestrel adding code to the pipeline

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

namespace KestrelTest
{
    public class Startup
    {
        public void Configure(
            IApplicationBuilder applicationBuilder,
            IHostingEnvironment hostingEnvironment)
        {
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            WebHost.CreateDefaultBuilder()
                .UseStartup<Startup>()
                .UseKestrel()
                .Build()
                .Run();
        }
    }
}

Within the Configure method we can start adding code to respond to different routes using the Map method, for example add the following to the Configure method

applicationBuilder.Map("/hello", app =>
{
   app.Run(async ctx =>
   {
      var request = 
         ctx.Request.Path.HasValue ? 
            ctx.Request.Path.Value.Substring(1) : 
            String.Empty;
       await ctx.Response.WriteAsync("Hello " + request);
   });
});
applicationBuilder.Map("/error", app =>
{
   app.Run(ctx => 
      Task.FromResult(
         ctx.Response.StatusCode = 404) 
   );
});

Note: The code is somewhat basic, obviously you would probably want to write some better code for extracting partial paths etc. from the routes/maps. However we’ll be covering a better alternative to this sort of code later in the post.

In the above we’ve created the equivalent of two “routes”. The first handles URL’s along the line of localhost:5000/hello/World where the return would become “Hello World”. The second route simply responds with a 404 for the URL localhost:5000/error.

We can also (as you’d expect) handle queries within our URL, so let’s say we expect this format URL, http://localhost:5000/hello?name=World, then we can amend our /hello code to the following

applicationBuilder.Map("/hello", app =>
{
   app.Run(async ctx =>
   {
      await ctx.Response.WriteAsync(
         "Hello " + ctx.Request.Query["name"]);
   });
});

These pieces of code write responses, but we can also insert code into the pipeline which doesn’t write to the response but instead might add debug/logging code. Other examples of usage might include (as per Writing Middleware) changes to the culture for the user response.

Here’s a simple example of such code, this is a little contrived as we’re going to (in essence) redirect calls to /hello path. Just place the following code before the applicationBuilder.Map method in the above

applicationBuilder.Use(async (ctx, next) =>
{
   if (ctx.Request.Path.Value == "/hello")
   {
      ctx.Request.Path = new PathString("/error");
   }
   await next.Invoke();
});

Note: there are redirect/URL rewriting capabilities already in ASP.NET Core, see URL Rewriting Middleware in ASP.NET Core.

Routing

In the previous example we demonstrated using the Map method to route our calls but ASP.NET Core libraries already supply a routing middleware which handles a lot of the standard routing type of functionality we’d expect. We can add the routing services by adding a method to the Startup class like this

public void ConfigureServices(
   IServiceCollection services)
{
   services.AddRouting();
}

Now the Configure method should look like this

public void Configure(
   IApplicationBuilder applicationBuilder,
   IHostingEnvironment hostingEnvironment)
{
   var routes = new RouteBuilder(applicationBuilder);
   routes.MapGet("hello/{name}", ctx =>
   {
      var name = ctx.GetRouteValue("name");
      return ctx.Response.WriteAsync($"Hello {name}");
   });

   applicationBuilder.UseRouter(routes.Build());
}

The RouteBuilder handles the routing in a more helpful/useful manner. Don’t forget to use the line applicationBuilder.UseRouter(routes.Build()); or you’ll find that the routes are not registered and hence your code will never get called.

References

ASP.NET Core MiddlewareRouting in ASP.NET Core

Kestrel – ASP.NET core web server

Kestrel is a .NET Core cross platform web server that can be used to host web sites, web/REST services etc.

Note: This code covers .NET core 2.0 and ASP.NET core 2.0.1

Take a look at Introduction to Kestrel web server implementation in ASP.NET Core for a great post about using Kestrel along with IIS, Nginx etc.

Getting Started

Let’s get started and build a very basic application running Kestrel.

  • Create a Visual C# | .NET Core | Console App (.NET Core) application
  • My project is named KestrelTest
  • Use NuGet to add the package Microsoft.AspNetCore

Now let’s create the most basic and most useless web server by writing the following code

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;

namespace KestrelTest
{
    public class Startup
    {
        public void Configure(IApplicationBuilder applicationBuilder,
            IHostingEnvironment hostingEnvironment)
        {
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            WebHost.CreateDefaultBuilder()
                .UseStartup<Startup>()
                .UseKestrel()
                .Build()
                .Run();
        }
    }
}

In Main we create the webserver and we supply the Startup application which we’d use to configure our services. Minimally we need the Configure method in the Startup object and notice we’re not adhering to any specific interface or type.

We could pass the args to the CreateDefaultBuilder if we want to start the application with certain arguments and/or use the UseKestrel override to create options for our server, but we’re aiming to just create the bare essentials of a Kestrel based web server in this post.

Now we can run this code and we’ll get, by default, a web server running and exposing port 5000 on localhost. However the server does nothing else, no static pages, nothing.

So let’s now add the NuGet package Microsoft.AspNetCore.StaticFiles and change our Configure method to look like this

public void Configure(
   IApplicationBuilder applicationBuilder,
   IHostingEnvironment hostingEnvironment)
{
   applicationBuilder.UseWelcomePage();
}

Now run the application and using your preferred web browser, navigate to localhost:5000 and you should see a ASP.NET Core Welcome Page.

Again this is of little use but does show that everything is working.

Serving up some static content

See Work with static files in ASP.NET Core for more in depth information.

Let’s now use Kestrel to serve up some static pages. Change the Configure method to look like this

public void Configure(
   IApplicationBuilder applicationBuilder,
   IHostingEnvironment hostingEnvironment)
{
   applicationBuilder.UseStaticFiles();
}

Now in your project folder (i.e. the folder with your Program.cs file) which should be the same as the Content root path shown when you run the application. Here you can add a wwwroot folder and place an HTML page in the folder, i.e. here’s a simply index.html file

<html>
    <body>
        Hello World
    </body>
</html>

Make sure you set the file to have the “Copy to Output Directory” option as “Copy if Newer” in the properties window in Visual Studio.

Run the application again and navigate to localhost:5000/index.html and you should see the text Hello World.

Middleware

As we’ve seen in this post, the design of Kestrel is to supply a default web server application which we can then add our middleware code to, turning the application into a static web server or adding ASP.NET MVC into the mix etc. We can implement our own middle ware (see ASP.NET Core Middleware) which can be used to handle requests via a middleware pipeline.

I’m not going to go into any real depth in terms of developing my own middleware as we can already use various libraries for this, but just to demonstrate how we can intercept a request, change the Configure method to look like this

public void Configure(
   IApplicationBuilder applicationBuilder,
   IHostingEnvironment hostingEnvironment)
{
   applicationBuilder.Run(async context =>
   {
      await context.Response.WriteAsync("***Hello World***");
   });
}

Now if we run up the application and navigate to localhost:5000 we should see ***Hello World*** returned.

References

Introduction to Kestrel web server implementation in ASP.NET Core
BenchmarksASP.NET Core Web Servers: Kestrel vs IIS Feature Comparison and Why You Need Both

Currying functions

Currying is probably better known within functional languages. In it’s simplest form we can view a currying as a way to declare a function and if a user of the function supplies less arguments than expected then a function is returned which takes the remaining arguments.

Let’s look at currying using a functional language such as F# first, as this really shows the usefulness of such a capability. We’ll define an add function which takes three parameters

let add a b c = a + b + c

Now we can write code such as

let r = add 1 2

Note: when we create a new function from our curried function, such as r in above, we can call this a partially applied function.

As you can see, we have not supplied all the arguments and hence r is not an integer but is instead a function which now accepts a single argument, i.e. the final argument the add function expects. Therefore we can write the following code against the returned function

let i = r 3

Now, i is an integer and contains the result of add 1 2 3 function call (i.e. the value 6).

Currying comes “built-in” syntactically in languages such as F#. We can write explicit code to demonstrate what in essence happens when we work within currying capable languages. Here’s an F# example which shows how we create functions returning functions along with closures to pass the preceding function arguments to each inner function

let add a = 
    let add1 b = 
        let add2 c = 
            a + b + c
        add2
    add1

Note: The F# compiler does NOT create the code equivalent to the above when we create functions unless the usage of the add method includes using it in a curried scenario.

The above is written in F# but you’ll notice that this same technique can easily be written in languages such as C#, Java etc. Here’s the same code in a verbose implementation in C#

public static Func<int, Func<int, int>> Add(int a) => 
   new Func<int, Func<int, int>>(b => (c => a + b + c));

Thankfully C# allows a less verbose syntax, so the above can be rewritten as

public static Func<int, Func<int, int>> Add(int a) =>
   b => (c => a + b + c);

To call such a function we’d need to write code such as

var i = Add(1)(2)(3)

This is not as elegant as the F# code (in my opinion) but does allow currying and partially applied functions in C#.

As you’d expect – another functional language, Scala, supports currying using the following syntax

def add(a : Int)(b : Int)(c : Int) = a + b + c;

val r = add(1)(2)_
// or alternate syntax
// val r = add(1)(2)(_)
val i = r(3)

Notice that we require the _ (underscore) to ignore the third argument and we need to wrap each argument within brackets (creating parameter groups) to enable the function to be curried. The missing last argument need now be enclosed within brackets.

Scala also allows us to create partially applied functions where it’s not just the last n parameters that make up the new function. For example (let’s change the argument types to a string to the output is more obvious.

def mid(a : String)(b : String)(c : String) = a + b + c;

def m = mid("Start ")(_:String)(" End")
println(m("Hello World"))
// outputs Start Hello World End

In this case we’re making a partially applied function using the curried function mid where in usage we miss out the middle parameter in the example usage. However we must also supply the type along with the _ placeholder.

Reading the BOM/preamble

Sometimes we get a file with the BOM (or preamble) bytes at the start of the file, which denote a UNICODE encoded file. We don’t always care these and want to simple remove the BOM (if one exists).

Here’s some fairly simple code which shows the reading of a stream or file with code to “skip the BOM” at the bottom

using (var stream = 
   File.Open(currentLogFile, 
      FileMode.Open, 
      FileAccess.Read, 
      FileShare.ReadWrite))
{
   var length = stream.Length;
   var bytes = new byte[length];
   var numBytesToRead = (int)length;
   var numBytesRead = 0;
   do
   {
      // read the file in chunks of 1024
      var n = stream.Read(
         bytes, 
         numBytesRead, 
         Math.Min(1024, numBytesToRead));

      numBytesRead += n;
      numBytesToRead -= n;

   } while (numBytesToRead > 0);

   // skip the BOM
   var bom = new UTF8Encoding(true).GetPreamble();
                    
   return bom.Where((b, i) => b != bytes[i]).Any() ? 
      bytes : 
      bytes.Skip(bom.Length).ToArray();
}

C# 7 Tuples

C#/.NET has had support for the Tuple class (a reference type) since .NET 4, but with C# 7 tuples now gets some “syntactic sugar” (and a new ValueTuple struct) to make them part of the language.

Previous to C# 7 we’d write code like this

var tuple = new Tuple<string, int>("Four", 4);

var firstItem = tuple.Item1;

Now, in a style more like F#, we can write the following

var tuple = ("Four", 4);

var firstItem = tuple.Item1;

This code makes the creation of tuples slightly simpler but we can also make the use of the “items” within a tuple more readable by using names. So we could rewrite the above in a number of ways, examples of each supplied below

(string name, int number) tuple1 = ("Four", 4);
var tuple2 = (name: "Four", number: 4);
var (name, number) =  ("Four", 4);

var firstItem1 = tuple1.name;
var firstItem2 = tuple2.name;
var firstItem3 = name;

Whilst not quite as nice as F# we also now have something similar to pattern matching on tuples, so for example we might be interested in creating a switch statement based upon the numeric (second item) in the above code, we can write

switch (tuple)
{
   case var t when t.number == 4:
      Console.WriteLine("Found 4");
      break;
}

Again, similar to F# we also can discard items/params using the underscore _, for example

var (_, number) = CreateTuple();

In this example we assume the CreateTuple returns a tuple type with two items. The first is simply ignored (or discarded).

IOException – the process cannot access the file because it is used by another process

I’m using a logging library which is writing to a local log file and I also have a diagnostic tool which allows me to view the log files, but if I try to use File.Open I get the IOException,

“the process cannot access the file because it is used by another process”

this is obviously self-explanatory (and sadly not the first time I’ve had this and had to try and recall the solution).

So to save me searching for it, here the solution which allows me to open a file that’s already opened for writing to by another process

using (var stream = 
   File.Open(currentLogFile, 
      FileMode.Open, 
      FileAccess.Read, 
      FileShare.ReadWrite))
{
   // stream reading code
}

The key to the File.Open line is the FileShare.ReadWrite. We’re interested in opening the file to read but we still need to specify the share flag(s) FileShare.ReadWrite.

How does yield return work in .NET

A while back I had a chat with somebody who seemed very interested in what the IL code for certain C#/.NET language features might look like – whilst it’s something I did have an interest in during the early days of .NET, it’s not something I had looked into since then, so it made me interested to take a look again.

One specific language feature of interest was “what would the IL for yield return look like”.

This is what I found…

Here’s a stupidly simple piece of C# code that we’re going to use. We’ll generate the binary then decompile it and view the IL etc.

public IEnumerable<string> Get()
{
   yield return "A";
}

Using JetBrains dotPeek (ILDASM, Reflector or ILSpy can ofcourse be used to do generate the IL etc.). So the IL created for the above method looks like this

.method public hidebysig instance 
   class [mscorlib]System.Collections.Generic.IEnumerable`1<string> 
      Get() cil managed 
{
   .custom instance void  [mscorlib]System.Runtime.CompilerServices.IteratorStateMachineAttribute::.ctor(class [mscorlib]System.Type) 
   = (
      01 00 1b 54 65 73 74 59 69 65 6c 64 2e 50 72 6f // ...TestYield.Pro
      67 72 61 6d 2b 3c 47 65 74 3e 64 5f 5f 31 00 00 // gram+<Get>d__1..
      )
   // MetadataClassType(TestYield.Program+<Get>d__1)
   .maxstack 8

   IL_0000: ldc.i4.s     -2 // 0xfe
   IL_0002: newobj       instance void TestYield.Program/'<Get>d__1'::.ctor(int32)
   IL_0007: dup          
   IL_0008: ldarg.0      // this
   IL_0009: stfld        class TestYield.Program TestYield.Program/'<Get>d__1'::'<>4__this'
   IL_000e: ret          
} // end of method Program::Get

If we ignore the IteratorStateMachineAttribute and jump straight to the CIL code label IL_0002 it’s probably quite obvious (even if you do not know anything about IL) that this is creating a new instance of some type, which appears to be an inner class (within the Program class) named <Get>d__1. The preceeding ldc.i4.s instruction simply pushes an Int32 value onto the stack, in this instance that’s the value -2.

Note: IteratorStateMachineAttribute expects a Type argument which is the state machine type that’s generated by the compiler.

Now I could display the IL for this new type and we could walk through that, but it’d be much easier viewing some C# equivalent source to get some more readable representation of this. So I got dotPeek to generate the source for this type (from the IL).

First let’s see what changes are made by the compiler to the Get() method we wrote

[IteratorStateMachine(typeof (Program.<Get>d__1))]
public IEnumerable<string> Get()
{
   Program.<Get>d__1 getD1 = new Program.<Get>d__1(-2);
   getD1.<>__this = this;
   return (IEnumerable<string>) getD1;
}

You can now see the newobj in it’s C# form, creating the <Get>d__1 object with a ctor argument of -2 which is assigned as an initial state.

Now let’s look at this lt;Get>d__1 generated code

[CompilerGenerated]
private sealed class <Get>d__1 : 
    IEnumerable<string>, IEnumerable, 
    IEnumerator<string>, IDisposable, 
    IEnumerator
{
   private int <>1__state;
   private string <>2__current;
   private int <>l__initialThreadId;
   public Program <>4__this;

   string IEnumerator<string>.Current
   {
      [DebuggerHidden] get
      {
         return this.<>2__current;
      }
   }

   object IEnumerator.Current
   {
      [DebuggerHidden] get
      {
         return (object) this.<>2__current;
      }
   }

   [DebuggerHidden]
   public <Get>d__1(int <>1__state)
   {
      base..ctor();
      this.<>1__state = param0;
      this.<>l__initialThreadId = Environment.CurrentManagedThreadId;
   }

   [DebuggerHidden]
   void IDisposable.Dispose()
   {
   }

   bool IEnumerator.MoveNext()
   {
      switch (this.<>1__state)
      {
         case 0:
            this.<>1__state = -1;
            this.<>2__current = "A";
            this.<>1__state = 1;
            return true;
          case 1:
            this.<>1__state = -1;
            return false;
          default:
            return false;
      }
   }

   [DebuggerHidden]
   void IEnumerator.Reset()
   {
      throw new NotSupportedException();
   }

   [DebuggerHidden]
   IEnumerator<string> IEnumerable<string>.GetEnumerator()
   {
      Program.<Get>d__1 getD1;
      if (this.<>1__state == -2 && 
          this.<>l__initialThreadId == Environment.CurrentManagedThreadId)
      {
          this.<>1__state = 0;
          getD1 = this;
      }
      else
      {
          getD1 = new Program.<Get>d__1(0);
          getD1.<>4__this = this.<>4__this;
      }
      return (IEnumerator<string>) getD1;
   }

   [DebuggerHidden]
   IEnumerator IEnumerable.GetEnumerator()
   {
      return (IEnumerator) this.System.Collections.Generic.IEnumerable<System.String>.GetEnumerator();
    }
}

As you can see, yield causes the compiler to create enumerable implementation for just that one of code.

Remoting in C# (legacy code)

In another post I looked at remoting using WCF but what were things like before WCF (or what’s an alternative to WCF)? I thought I’d post just the bare bones for getting a really simple service and client up and running.

Note: Microsoft recommends new remoting code uses WCF, so this post is more for understanding legacy code.

Note: I am not going to go into the lifecycle, singletons/single instances etc. here, I’m just going to concentrate on the code to get something working.

The Server

As per my previous post on WCF remoting, we’re going to simply create a console application to act as our server, so go ahead an create one (mine’s named OldRemoteServer) and then add the following

public interface IRemoteService
{
   void Write(string message);
}

into a file of it’s own, then our client can link to it in our client’s Visual Studio solution.

Here’s an implementation for the above

public class RemoteService : MarshalByRefObject, IRemoteService
{
   public void Write(string message)
   {
      Console.WriteLine(message);
   }
}

Note: The implementation needs to be derived from MarshalByRefObject or the class needs to be marked with the Serializable attribute or implement ISerializable which obviously makes sense. We’re solely going to look at MarshalByRefObject implementation for now as these will be passed by reference to the client, whereas the serializable implementations are aimed at passing by value.

Now let’s put some code in the Main method of our Console app.

var channel = new TcpChannel(1002);
ChannelServices.RegisterChannel(channel, false);

RemotingConfiguration.RegisterWellKnownServiceType(
  typeof(RemoteService), 
  "Remote", 
   WellKnownObjectMode.Singleton);

// now let's ensure the console remains open
Console.ReadLine();

In the above code we’re using a Tcp channel with the port number 1002 and in the RegisterWellKnownServiceType, we’re registering the service type (this should be the implementation, not the interface) and supply a name “Remote” for it. In this case I’m also setting it to be a Singleton.

You’ll need to add a reference to System.Runtime.Remoting and the following using clauses

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

The Client

Create another Console application to simply test this and add the file with the IRemoteService interface.

I’ve simply added it by selecting the client solution, the Add… | Existing Item, locate the file and instead of clicking the Add button select the dropdown to Add As Link. Then if you change the interface it’ll be immediately reflected in the client – ofcourse in a more complex application we’d have the interfaces in their own assembly.

Now to get the client to call the server we simply place the following in the Main method of the Console app.

var obj = (IRemoteService)Activator.GetObject(
   typeof(IRemoteService), 
   "tcp://localhost:1002/Remote");

obj.Write("Hello World");

In the above you’ll see that we use the Activator to get an object and supply the type, then the next line shows we’re using the Tcp channel, port 1002 as set up in the server and the name from the server we game our object “Remote”.

This creates a transparent proxy which we then simply call the interface method Write on.

Configuration

In the above example code I’ve simply hard-coded the configuration details but ofcourse we can create a .config file to instead handle such configurations.

Let’s replace all the server Main method code with the following

RemotingConfiguration.Configure("Server.config", false);

Add an App.config to the project, we’re going to rename it Server.config for this example and ensure that the files’s properties (in Visual Studio) are set to Copy Always (or Copy if newer) to ensure the copy in the bin folders is upto date.

Now here’s the Server.config which recreates the singleton, tcp, port 1002 settings previously handled in code

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
  <application>
    <service>
      <wellknown
        type="OldRemoteServer.RemoteService, OldRemoteServer"
        objectUri="Remote"
        mode="Singleton" />
    </service>
    <channels>
      <channel ref="tcp" port="1002"/>
    </channels>
  </application>

  </system.runtime.remoting>
</configuration>

Now if you run the server and then the client, everything should work as before.

Next up, let’s set the client up to use a configuration file…

So we’ll add an App.config file to the client now, but let’s name it Client.config and again set the Visual Studio properties to ensure it’s always copied to the bin folder.

Add the following to the configuration file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <client>
        <wellknown 
          type="OldRemoteServer.RemoteService, OldRemoteServer" 
          url="tcp://localhost:1002/Remote" />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>

It might seem a little odd that we’re declaring the type as the implementation within the server code, but the reason will hopefully become clear.

Add a reference within the client to the RemoteServer (if you have the implementation in a DLL, all the better, we didn’t do that, so I’m referencing the server EXE itself). This now give us access to the implementation of the RemoteService.

Change the client Main method to

RemotingConfiguration.Configure("Client.config", false);

var obj = new RemoteService();
obj.Write("Hello World");

don’t forget to add the using clause

using System.Runtime.Remoting;

This bit might seem a little strange, based upon what we’ve previously done and how we’ve kept a separation of interface and implementation. Aren’t we now simply creating a local instance of the RemoteService, you might ask.

Well try it, run the server and then the client and you’ll find .NET has created a transparent proxy for us and calls to the RemoteService will in fact go to the server.

Whilst this makes things very easy, I must admit I prefer to not reference the implementation of the RemoteService.

What about named pipes?

Let’s now look at the changes to use the IPC protocol (for implementing named pipes) in .NET remoting. I’ll just briefly cover the changes required to implement this.

To start with let’s rewrite the server and client in code. So first the Main method in the server should now look like

var channel = new IpcChannel("ipcname");
ChannelServices.RegisterChannel(channel, false);

RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteService),
   "Remote",
   WellKnownObjectMode.Singleton);

Console.ReadLine();

So the only real difference from the Tcp implementation is the use of an IpcChannel and the name supplied instead of a port.

The client then looks like this

var obj = (IRemoteService)Activator.GetObject(
   typeof(IRemoteService), 
   "ipc://ipcname/Remote");

obj.Write("Hello World");

Simple enough.

Now let’s change the code to use a configuration file.

The server Main method should now look like this

RemotingConfiguration.Configure("Server.config", false);
Console.ReadLine();

and the Server.config should look like this

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
  <application>
    <service>
      <wellknown
        type="OldRemoteServer.RemoteService, OldRemoteServer"
        objectUri="Remote"
        mode="Singleton" />
    </service>
    <channels>
      <channel ref="ipc" portName="ipcname"/>
    </channels>
  </application>

  </system.runtime.remoting>
</configuration>

The client code should be

RemotingConfiguration.Configure("Client.config", false);
var obj = new RemoteService();
obj.Write("Hello World");

and it’s Client.config should look like this

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <client>
        <wellknown 
          type="OldRemoteServer.RemoteService, OldRemoteServer" 
          url="ipc://ipcname/Remote" />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>