Hosting WCF Services in an ASP.NET Web Application
July 1, 2011Self-Hosting WCF Services
September 2, 2011In this post I will explain how a WCF service can be created using a Synergy .NET Interop project. In my earlier post I explained how to use xfNetLink .NET to create a WCF service, which provided an easy way to create a WCF service for developers who were already using xfNetLink .NET and xfServerPlus. Now I want to show you an alternate approach that is somewhat similar in nature, but which does not require the continued use of xfNetLink .NET and xfServerPlus in final solution. Of course this might not be what you want if your Synergy server is a non-Windows system.
This is the fourth in a series of posts relating to the various ways in which Synergy developers can use of Windows Communication Foundation (WCF) when building their applications. The posts in the series are:
- Building Distributed Apps with Synergy/DE and WCF
- Exposing WCF Services using xfNetLink .NET
- Hosting WCF Services in an ASP.NET Web Application
- Exposing WCF services using Synergy .NET Interop (this post)
- Self-Hosting WCF Services
- Exposing WCF services using Synergy .NET
What is Synergy .NET Interop
Before we get started we better make sure you know what a Synergy .NET Interop project is. In a nutshell an Interop project is a way of creating a .NET assembly containing various classes, where the external interface of those classes is defined by a collection of Traditional Synergy xfServerPlus methods, and the Synergy records that are referenced by the parameters of those methods. The idea is that the classes exposed by the assembly created by an Interop project have the exact same external interface that would be created if those same methods were defined in a Method Catalog and exposed via xfServerPlus and xfNetLink .NET. So the primary use case for an Interop assembly is to allow developers with existing applications which use xfNetLink .NET and xfServerPlus to factor those tools out of their solution, resulting in a pure .NET application.
In the same way that GENCS has an optional –W command line switch which essentially transforms the resulting .NET assembly into a WCF service, the Synergy .NET Interop project has a project option which does the exact same thing.
So let’s get started. Here’s how to do it. Remember, an Interop project allows you to expose a Synergy .NET assembly based on one or more traditional Synergy methods and records, but there are some prerequisites:
- The Synergy methods must make use of the recently introduced attributes and documentation comments, so that the external interface of the method is entirely defined within the code. The Interop project does not use a Synergy Method Catalog.
- The records that are referenced by the parameters of the methods must be defined in a repository, but this would always have been the case if you were using xfServerPlus.
- Generally the data files that are accessed by your methods should be moved to the Windows server where the WCF service will be hosted, so that the files can be accessed locally. If your data files need to stay on a non-Windows server then of course you could use xfServer to access the files remotely.
- You’ll need to have a copy of the source code for the Synergy methods available on the Windows development system where you are using Synergy .NET.
These are the steps that you’ll need to complete in order to create a Synergy .NET Interop assembly from your existing Synergy methods and repository structure definitions:
Create an Interop Project
The first step in the process is to create a new Synergy .NET Interop Assembly project:
- Open Visual Studio and create a new Synergy .NET Interop Project.
- From the menu, select File > New > Project.
- In the Installed Templates list select Synergy/DE > Interop.
- Set the name and location of the new project as required (here I’m naming the project MyInteropAssembly and setting the location to my c:temp folder).
- Click the OK button to create the new project.
When you create an Interop project a new source file called SynergyRoutines.dbl is automatically included in the project. This file contains various utility routines that are used by the interop project in order to expose the same interface that xfNetLink .NET does. You shouldn’t need to be concerned with this code, and shouldn’t modify it. Simply close the file.
Add Synergy Method Source Files
Having created the Interop project the next step is to add the source code for your Synergy methods to the project. Remember that the methods that you include in an Interop project are Traditional Synergy subroutines and functions that include whatever {xfMethod} and {xfParameter} attributes are required in order to completely document the external interface of the methods within the source files.
For clarity when creating an Interop project I also like to include my method source files in a folder within the project, and I generally name the folder “Methods”. This is entirely optional though.
- In solution Explorer, right-click on your Interop project and from the context menu select Add > New Folder.
- Change the name of the folder to Methods and press enter.
- Right-click on your new Methods folder and from the context menu select Add > Existing Item….
- Use the resulting open file dialog to browse to the location of your Synergy method routines, select them all, and then click the Add button to add the routines to your project.
In Solution Explorer your project should now look something like the image on the right.
Before we move on let me make a couple of things clear. Firstly it is important that you know that when you add existing files to a project using Add > Existing Item, those files are COPIED into your project folders. If you prefer to leave the source files in their existing location then you can use Add > Reference Existing Item.
The second thing that you need to understand is that in the example I am using here the nature of the methods that I am using is relatively simple, and the methods don’t have external dependencies on other routines in libraries, don’t use include files, etc. If your methods do have such dependencies then you will need to decide how best to resolve those dependencies.
Set Environment Variables
It is likely that you will need to set some environment variables in order for your code to be able to compile and run. It is almost certain that you will need to at least set the environment variables that allow your repository to be located and accessed, and in the case of the code that I am using, at runtime an environment variable named DAT is used to specify the location of the data files that are accessed by the code.
Synergy .NET development projects include the ability to set environment variables in the development environment via properties of the project:
- In Solution Explorer, right click on your project and from the context menu select Properties.
- In the project properties dialog, to the left side, select the tab named Environment Variables.
- Set whatever environment variables are required in order for your code to compile and run.
- Save your changes by selecting File > Save from the menu.
- Close the project properties dialog.
In the case of the code I am using for this example I needed to set the following environment variables:
By the way, the tools in Synergy .NET also honor the same mechanisms for setting environment variables as Traditional Synergy on the Windows platform. So if the environment variables that you need are already present in your system environment, or are provided by the synergy.ini or synuser.ini files then you won’t need to set them here.
Build an Interop Assembly
You should now be able to build your interop assembly.
- In Solution Explorer, right-click on your project and from the context menu select Build.
- Check the output window, you should see something like this:
------ Build started: Project: MyInteropAssembly, Configuration: Debug Any CPU ------ ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
If your assembly did not build then you’ll need to resolve any errors that you may have before you proceed. The most likely cause for errors at this point will be external dependencies that are not catered for.
Check out what happened in your project. If you look in Solution Explorer you will notice that a new folder called GeneratedCode was created, and some new source files were added to the folder. These new files are at the center of how Interop projects work.
The method source files that you added to the project, in the Methods folder, were Traditional Synergy subroutines and functions. The job of an Interop project is to expose the functionality of those methods in the same way that xfNetLink .NET’s GENCS utility does, and GENCS creates .NET classes that represent the Synergy methods, and the data structures exposed by those Synergy methods.
The Interop project essentially does the same thing, except that where GENCS created C# code which uses xfNetLink .NET and xfServerPlus to call the Synergy methods, the Interop project creates Synergy .NET code which calls the Synergy methods directly.
In the code used in my example the Synergy methods that I added to the project were all part of an interface named “SynergyServer”. This was defined by the {xfMethod} attributes that were present in each of the source files that I included into the project. You will notice that the GeneratedCode folder now includes a source file named SynergyServer.dbl, and if you were to look in the source file you would see that it contains a class named SynergyServer, which in turn contains methods named GetAddressForUpdate, GetAllCustomers and so on. These methods correspond to the Synergy methods that I originally included in the project.
Additionally you will notice that the GeneratedCode folder also contains several source files which represent the record definitions which are exposed by the parameters of my methods. For each record that is exposed the interop project has created a class to represent that data structure. These classes are named Address, Address_type, Contact and so on.
However, if you were to look in the source files that have been generated into the GeneratedCode folder you might notice that these generated classes do not contain any ServiceContract, OperationContract, DataContract or DataMember attributes. In other words, the classes can’t currently be exposed via WCF.
Note: You should not make changes to any of the code in the GeneratedCode folder, because this code will be recreated each time you build the project.
Expose a WCF Service
As I briefly discussed in an earlier post, in order for classes to be exposed via WCF it is necessary to apply various attributes to those classes:
Nature of Item | Required Attribute |
Class containing callable methods | ServiceContract |
Callable method | OperationContract |
Class defining a data structure | DataContract |
Accessible member in a data structure | DataMember |
In an Interop project, these attributes can be automatically added to the generated classes by enabling a project option called “Generate WCF Contracts”.
- In Solution Explorer, right-click your project and select Properties.
- In the project properties dialog, to the left side, select the tab named Interop.
- Check the Generate WCF Contracts option.
- In most cases it’s also a good idea to set the Generate out parameters property to out instead of the default value of “ref”.
- Save your changes by selecting File > Save from the menu.
- Close the project properties dialog.
- In Solution Explorer, right-click on your project and from the context menu select Build.
- Check the output window and make sure that your assembly built correctly.
Note: The default behavior of generating out parameters as ref is to maintain compatibility with what GENCS does by default, but when exposing a new WCF service to a new client application you would always want output parameters defined as type out.
Now take a look at the various source files in the GeneratedCode folder. You should notice that the ServiceContract, OperationContract, DataContract and DataMember attributes are present as required.
Host the Service
That’s it, you just used a Synergy .NET Interop project to define and create a WCF service. Of course before you can actually do anything with the service you will need to host it somewhere. One option is to host the service in an ASP.NET Web Application as described in my earlier post.
However, sometimes developers don’t want to have to setup and maintain an IIS web server simply to host a WCF service. Luckily there are other ways of hosting a WCF service that do not require IIS, and that will be the topic of the next post in this series.