Open Menu

Synergex Blog


Windows Reimagined

By Steve Ives, Posted on September 14, 2011 at 12:18 am

Well, all I can say is “WOW”! The first day of the Microsoft BUILD conference is over, and it’s been a LONG day, and it’s been a BUSY day, and it’s been an EXCITING day. Wow!

I’m buzzed … and I’m really quite surprised by that statement. I arrived in Anaheim a little over 24 hours ago, and to be quite honest I was a little skeptical about the whole thing. As you may know from a couple of recent posts, I had started to do some research about what Windows 8 might mean to Synergex, and to our customers, and to our customers customers … and to be quite honest I had more questions than answers. I was more than a little concerned that Microsoft were all set to try to change the Windows world … which they are … but perhaps with less than the amount of (in my opinion) required consideration for existing customers, and applications, and technologies, and tools.

Specifically, I was concerned that there was a lot of talk about HTML5, and of CSS, and of JavaScript … but very little talk about XAML, and C#, and third-party languages like Synergy .NET, and so on. I was concerned that Microsoft were set to not only reimagine Windows, but also reimagine all of the development tools that are used to build Windows applications.

But … big sigh of relief … from me and several thousand other people in the room … although there is a definite emphasis on new development tools which will soon be available within the Microsoft development toolset, i.e. extended support for tools like HTML5, CSS and JavaScript,  there is also a consistent message that existing .NET toolsets are still completely valid and will continue to be so.

On the platform side … WOW! Most of the information to date has centered around videos of demos dating back to early June, and those demos were pretty impressive, Well, I can tell you that things have moved on quite significantly since then, and although Windows 8 is still only in a “Developer Preview” (i.e. pre-beta) state … it’s looking REALLY GOOD!

Of course there are bugs, of course there are glitches, but on the whole people at this conference are pretty excited about what is coming. And that includes the four Synergex employees that are here … after a long day at the conference, and a pretty good stint in the bar afterwards, we’re bouncing ideas around, and coming up with all of these “what if’s”, and seeing the real possibility of Synergy developers being able to fully participate in these exciting new technologies.

Of course some of the reason for this is as a direct consequence of the tens of thousands of man hours of work that have been invested in the various Synergy products in recent years. But also it is with the realization that there is more work still to be done, because the goal posts just got moved in a fairly significant way. But … because of where we know we are now, where we now know we need to be actually doesn’t seem that far away … WOW!

There are exciting times ahead … there are challenges also, but I firmly believe that we’re on the right track.

If you’re interested in the future of Windows then I would strongly recommend that you watch the keynote speech from todays conference, you can find it and many other interesting videos here:

http://www.buildwindows.com

By the way, I am writing this post on my new Samsung Windows 8 “Slate” PC. Those who know me would tell you that I develop on Windows, and Unix, and Linux, and OpenVMS … but I’m an Apple guy at heart. I have an iPhone, and an iPad, and a couple of Macs … and I LOVE those things. But … I think that Microsoft Windows 8 might just change the world. It’s an operating system for the PC, and that PC might just be a Slate (tablet). The point is that today I was convinced that the best of both worlds really can be built into one operating system that can run equally well on different types of devices. I LOVE my iPad but I can’t run hundreds of thousands of existing desktop apps on it, and despite good intentions iOS is jus WAY too restrictive. What Microsoft showed us and gave us today is really cool … it’s a tablet, but it’s also a PC … WOW!


Windows 8 and Screen Resolution

By Steve Ives, Posted on September 8, 2011 at 4:10 pm

If you’re thinking of purchasing a new laptop, or a new flat-panel monitor for your desktop PC, you might want to think a carefully about the resolution of the screen that you select. Because if you’re purchasing new hardware now, you’re likely to want to run Windows 8 on that hardware before the end of its useful life.

According to early information from Microsoft, both the resolution and aspect ratio of the screen will become more important if you want to be able to take advantage of all of the new features available in the new Metro UI.

For the best experience with Windows 8, and in order to be able to take advantage of all of the new Metro UI features, you need a wide-screen with a 16 x 9 aspect ratio and a minimum pixel resolution of 1366 x 768. If your system meets or exceeds these specifications then you should be in good shape, and most will.

However, if your display does not have a wide-screen aspect ratio then you won’t be able to use all of the features of the Windows 8 Metro UI. Specifically the “Snap” feature which allows two “tailored” metro applications (or one tailored application and the traditional Windows Aero desktop) to be docked side-by-side will not be available. By the way, the term tailored application seems to be what Microsoft are using to refer to apps designed to take advantage of the Metro UI under Windows 8. I can’t help wondering if the choice of this term is to make us lowly software developers think that we just need to do a little “tailoring” here and there to support the new UI … in the same way that cell-based applications had to be “tailored a little” to move to Windows under UI Toolkit! Time will tell I guess.

By the way … don’t confuse the windows 8 “Snap” feature with another feature that they introduced in Windows 7 called … “Snap”!!! Although similar, they are not the same thing. Note that the Windows 7 desktop snap feature will still work on the traditional desktop, even if your system doesn’t support the Windows 8 Snap feature. All very confusing!

Finally, although uncommon some netbook PC’s are equipped with displays with less than 768 vertical pixels (e.g. 1024 x 600). Apparently displays this small will not support the new Metro UI at all, although the traditional Windows Aero UI will still work on these systems.

This information was taken from a video of a Microsoft event for various hardware partners which was held during the Computex 2011 in Taipei during early June 2011. If you’re interested in the full video, I’ve embedded it below.


Exposing WCF Services using Synergy .NET

By Steve Ives, Posted on at 12:54 pm

In this post I will explain how you can use Synergy .NET to expose a WCF service. I’ll be showing you how to create WCF service and data contracts totally from scratch, using Synergy .NET. We’ll be defining new classes, not working with existing routines and records. That’s not to say that you can’t work with existing routines and records, in fact you may well chose to do so WITHIN a service that you create, but the focus of this post is on writing new code for the future.

This is the sixth 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:

  1. Building Distributed Apps with Synergy/DE and WCF
  2. Exposing WCF Services using xfNetLink .NET
  3. Hosting WCF Services in an ASP.NET Web Application
  4. Exposing WCF services using Synergy .NET Interop
  5. Self-Hosting WCF Services
  6. Exposing WCF services using Synergy .NET (this post)

 

In earlier posts I demonstrated how it was possible to expose WCF services using existing source code, either by transforming an xfNetLink .NET assembly into a WCF service, or by adding the traditional Synergy subroutines and functions that existed “underneath” an xfNetLink .NET assembly to a new Synergy .NET Interop project. There are valid use cases for both of these strategies, depending on what you’re starting with, however there are also some disadvantages to both approaches.

Perhaps the most significant disadvantage is that the external interface of the WCF service contracts that get exposed are defined by the parameters and return values of one or more traditional Synergy routines. And the data contracts are defined by Synergy record layouts defined in a repository. Also the actual WCF contracts that are exposed are under the control of the code generators that create the contracts, either GENCS, or the logic within the Interop project. This means that as a developer you’re kind of stuck with the defaults that those tools provide.

WCF has diverse capabilities which are defined and controlled through a large number of code and configuration options, and many of these are controlled via in-code attributes which are applied to the service and data contracts that make up a service. But when you work with services that are generated for you you don’t get to determine what options are used. So in some cases you might find that working with generated services is a little too restrictive.

This post will show how to create your own WCF services from scratch, in a way that makes all of the capabilities of WCF available to you.

The WCF Service Library Template

Although it has been possible to create WCF services with Synergy .NET since the product was introduced in version 9.5.1, the process became a lot easier in 9.5.1a. This was because we added a new project template called WCF Service Library. To create a new WCF service we simply start Visual Studio and create a new project based on the WCF Service Library template:

image

When you use the project template you create a new class library which is pre-configured appropriately for the development of WCF service and data contract classes.

imageOver and above a regular class library, a WCF Service Library development project will include:

  • References to the following .NET Framework assembles
    • System.Core
    • System.Runtime.Serialization
    • System.ServiceModel
    • System.Xml
  • An example of how to define WCF service and data contracts.
    • IService1.dbl
  • An example of how to implement the service defined by a service contract.
    • Service1.dbl

 

Before we go too much further let me make it clear that I don’t particularly like the example code that is provided by the project template, despite being the one who actually provided it for the distribution! But there is a good reason why the example code is the way that it is. That reason is that the example implements in Synergy the the exact same example that Microsoft provide when you create a new WCF Service Library using either C# or Visual Basic.

Service Contracts

So what do we have in the example? Most developers agree that it is good practice to separate the definition of a service contract from the actual implementation of the contract, and for service contracts this is achieved using an interface. In the example file called IService1.dbl you will find code like this:

WCF Service Contract
  1. import System
  2. import System.Collections.Generic
  3. import System.Runtime.Serialization
  4. import System.ServiceModel
  5. import System.Text
  6.  
  7. namespace MyWcfServices
  8.  
  9.     {ServiceContract}
  10.     public interface IService1
  11.         
  12.         {OperationContract}
  13.         method GetData, string
  14.             required in val, int
  15.         endmethod
  16.         
  17.         {OperationContract}
  18.         method GetDataUsingDataContract, @CompositeType
  19.             composite, @CompositeType
  20.         endmethod
  21.         
  22.         ;;TODO: Add your service operations here
  23.         
  24.     endinterface
  25.     
  26. endnamespace

 

The example defines a WCF service in a class named Service1 and therefore, following accepted best practices, the name of the interface that defines the external view of the class is prefixed with a capital I. You will notice that the {ServiceContract} attribute is applied to the interface, which essentially means that any class which implements the interface will expose a WCF service contract.

Within the interface you will see that the example code defined two methods, named GetData and GetDataUsingDataContract. Both of these methods have the {OperationContract} attribute applied, which means that the methods will be exposed as operations of the WCF service … or in other words they are methods that a remote client accessing the service may call.

The GetData method accepts a single parameter which is an integer number, and has a return type of string.

The GetDataUsingDataContract method on the other hand has a single single parameter which is an object of type “CompositeType” and also returns an object of the same type. CompositeType is a class representing a complex data type (think OO version of a record) and is defined a little further down in the code:

By the way, you will notice that the methods that are described in the interface do not have accessibility specified. This is because by convention, all members of an interface are considered public. You will also notice that there is no procedure division specified … there is no PROC statement. This is because the role of an interface is simply to DEFINE requirements for a class, or rather for the external interface of a class. Interfaces do not include any logic … that will be added in a class which IMPLEMENTS the interface.

Data Contracts

Data contracts define complex data types (data classes) that can be passed from a client to a service or returned from a service back to a client, and are simply defined via a class with public properties of the appropriate types.

In the example the class named CompositeType has two public properties, one of type boolean named BoolValue, and one of type string named StringValue. As is often the case, the value of the public properties is propagated within the class by storing the actual value of the property in private variables, in this case the mBoolValue and mStringValue fields.

WCF Data Contract
  1. import System
  2. import System.Collections.Generic
  3. import System.Runtime.Serialization
  4. import System.ServiceModel
  5. import System.Text
  6.  
  7. namespace MyWcfServices
  8.  
  9.     ;;Use a data contract as illustrated in the sample below to
  10.     ;;add composite types to service operations
  11.     {DataContract}
  12.     public class CompositeType
  13.  
  14.         private mBoolValue, Boolean, true
  15.         private mStringValue, String, "Hello "
  16.         
  17.         {DataMember}
  18.         public property BoolValue, Boolean
  19.             method get
  20.             proc
  21.                 mreturn mBoolValue
  22.             endmethod
  23.             method set
  24.             proc
  25.                 mBoolValue = value
  26.             endmethod
  27.         endproperty
  28.         
  29.         {DataMember}
  30.         public property StringValue, String
  31.             method get
  32.             proc
  33.                 mreturn mStringValue
  34.             endmethod
  35.             method set
  36.             proc
  37.                 mStringValue = value
  38.             endmethod
  39.         endproperty
  40.  
  41.     endclass        
  42.  
  43. endnamespace

 

What makes the CompositeType class a WCF data contract is the presence of the {DataContract} attribute immediately before the class declaration, and the {DataMember} attributes immediately before the declaration of each of the public properties. The {DataContract} attribute is used to ensure that it is possible to serialize an instance of the class for transmission over the wire between a client and a server, and the {DataMember} attributes define which members of the class will be included in that serialization, or in simpler terms, which members will be visible to client applications.

It should be noted that, despite being the case in the simple example provided by the project template, it is somewhat unusual to define multiple types within a single source file as is the case here. In a real application it is likely that each interface would be defined in its own source file, as would each data class. There is nothing technically wrong with the approach used in the example, and it does keep the definition of all of the contracts for a service together in one place, but you don’t have to do it that way.

Implementing a WCF Service

So in the simple example provided by the WCF Service Library project template we have looked at the definition of the service and data contracts for Service1 in the source file IService1.dbl. Now it’s time to look at the code that actually implements the service itself. That code is found in Service1.dbl.

WCF Service Implementation
  1. import System
  2. import System.Collections.Generic
  3. import System.Runtime.Serialization
  4. import System.ServiceModel
  5. import System.Text
  6.  
  7. namespace MyWcfServices
  8.     
  9.     public class Service1 implements IService1
  10.         
  11.         public method GetData, String
  12.             required in val, int
  13.             endparams
  14.         proc
  15.             mreturn String.Format("You entered: {0}", val)
  16.         endmethod
  17.         
  18.         public method GetDataUsingDataContract, @CompositeType
  19.             composite, @CompositeType
  20.             endparams
  21.         proc
  22.             
  23.             if (composite==^null)
  24.                 throw new ArgumentNullException("composite")
  25.             
  26.             if (composite.BoolValue)
  27.                 composite.StringValue = composite.StringValue + "Suffix"
  28.             
  29.             mreturn composite
  30.             
  31.         endmethod
  32.         
  33.     endclass
  34.     
  35. endnamespace

    

The code above is the code that implements Service1. You will notice that this is achieved by writing a class which implements the interface that describes the service contract that we talked about earlier.

Writing a class which implements an interface is simply a matter of ensuring that the class includes at least the members that are described by the interface … in this case the GetData and GetDataUsingDataContract methods. The class may also include other members not described in the interface, but MUST at least contain the members described by the interface.

You will also notice that both of the methods required by the interface are declared with PUBLIC accessibility. As mentioned earlier this is a requirement when implementing an interface. When we implement an interface we include the code that each method in the interface will execute, so here is where the actual functionality of the service is defined.

In the example code the GetData method simply takes the integer value that was received from the client and uses that value in a string which is returned to the client. So if a client application connects to an instance of this service and calls the GetData method passing a value of 5, the return value of the method call will be the string You Entered: 5.

The GetDataUsingDataContract method checks to ensure that an instance of the CompositeType class was received, than if the objects BoolValue property is set to true it appends the string Suffix to whatever is the current value of the objects StringValue property. The object is then returned via the method return value. Yea, I know, the dev at Microsoft must have been smoking something pretty questionable when they wrote this example. Something more meaningful would have been nice, but it is what it is!

Writing a WCF Service

So, there you have it. Writing a WCF service in Synergy .NET is pretty straight forward. You basically need to:

  1. Create a new assembly using the WCF Service Library project template.
  2. Define the external interface of your service via an interface that describes the service and operation contracts, and any data classes that may be required to define the data contracts that you need.
  3. Create a class which implements the service contract and includes the necessary functionality.

And remember we’re working in Synergy .NET here, so we have the full power of Synergy at out fingertips. If we need to access Synergy data that’s local to where the service will be hosted then we can go ahead and access that data directly, but if the data is remote then we can use xfServer to get to it – regardless of the system it resides on. We could also use an xfNetLink .NET assembly to allow us to get back into our traditional Synergy business logic, for all or part of the logic for the service. And of course we still have access to the SQL Connection API in order to access any relational databases that we may need to use. Of course we could also use other mechanisms in the .NET Framework to access a wide variety of data sources too.

Hosting the Service

If you’ve read the earlier posts in this series then you will already know that creating a WCF service is only part of the story, it also needs to be hosted somewhere. This has already been discussed in two earlier posts, so I don’t intend to repeat the information here.


Self-Hosting WCF Services

By Steve Ives, Posted on September 2, 2011 at 4:17 pm

Having defined a WCF service in code, and built that code into an assembly, a runtime instance of the service must be “hosted” somewhere in order for other application to be able to connect to and interact with the service. There are several ways to host WCF services. In an earlier post I described how to Host a WCF Service in an ASP.NET Web Application, which is a commonly used approach. But in some situations, for example if the only requirement for an IIS web server is to host a WCF service, it is preferable to host a service in a different way. In this post I will describe how to do just that, by leveraging capabilities of the .NET Framework which allow WCF services to be “self hosted”.

This is the fifth 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:

  1. Building Distributed Apps with Synergy/DE and WCF
  2. Exposing WCF Services using xfNetLink .NET
  3. Hosting WCF Services in an ASP.NET Web Application
  4. Exposing WCF services using Synergy .NET Interop
  5. Self-Hosting WCF Services (this post)
  6. Exposing WCF services using Synergy .NET

What is Self Hosting?

As its name suggests, self hosting a WCF service refers to the ability to host a WCF service within another application that you write, rather than hosting the service in a container such as that provided by Internet Information Services (IIS), or Windows Process Activation Services (WAS).

The .NET Framework provides various classes that can be used to host WCF Services within the context of a .NET application. This could be any type of .NET application, including console applications and desktop applications. However, in most cases WCF services need to be continually available, and it is often not convenient to host a service in a console or desktop application, because those applications typically execute in the context of a logged in user session.

A Windows Service application on the other hand can provide an excellent mechanism for hosting a WCF service. Windows Services are generally designed to automatically start when a system boots, stopped when the system is closed down, be continually available while the system is running, and are not associated with the desktop of any logged in user.

Since 9.5.1a Synergy .NET has included a project template which makes creating a Windows Service very easy, and as you are about to see, adding the code necessary to instantiate and host a WCF service is relatively straight forward.

Creating a WCF Service

In this post I’m assuming that you have already created a WCF service that you wish to host. If you have read the earlier posts in this series you will already know of two ways to create a WCF service, and in a later post I’ll show you another way.

Creating a Windows Service

Using Synergy .NET it is very easy to create a Windows Service. We provide a project template called “Windows Service”, and when you create a new project from the template you essentially have all of the code that you need to implement the service. Of course, apart from starting and stopping a service the default code that you get from the template doesn’t actually do anything … that’s where you come in!

You’ll need a Windows development system with the following products installed

  • Visual Studio 2010 Professional (or higher / later)
  • Synergy/DE 9.5.1a (or later)
  • Synergy Language Integration for Visual Studio 9.5.1a (or later)

 

Follow these steps to create a new Windows Service:

  • Start Visual Studio
  • From the menu, select File > New > Project.
  • From the installed templates list, select Synergy/DE.
  • From the project templates list select Windows Service.
  • Provide a name for the project and set its location.
  • Click the OK button to create the new project.

 

image

As you can see, in my example I have named my service MyWcfHostService and have created the project below my c:temp folder.

imageOnce the Windows Service project has been created, if you look in Solution Explorer you should see something like this:

You will notice that three source files were added to the project. In my example the file MyWcfHostService.dbl contains the code for the service itself, MyWcfHostServiceInstaller.dbl contains code used when the service is registered (installed), and Program.dbl is simply the main-line program that actually launches the service when the process starts.

Take a look at the main service source file (the one that ends …Service.dbl) and you will see that the code is relatively self explanatory. The class defined in the source file extends a parent class called ServiceBase. This means that our class has inherited a lot of functionality which essentially makes it a Windows Service.

You’ll also see that the class has a constructor method with the same name as the class itself, and the constructor calls a method called InitializeComponent, which sets various properties in order to configure various capabilities of the service.

private method InitializeComponent, void
    endparams
proc
    this.ServiceName = "MyWcfHostService"
    this.AutoLog = true
    this.CanPauseAndContinue = false
    this.CanHandlePowerEvent = false
    this.CanShutdown = false
    this.CanStop = true
endmethod

All Windows services have the ability to be started, and as you can likely derive from the code, by default a new service has the ability to be stopped, but not to be paused and continued, or to respond to changes in the systems power state (mains vs. battery).

So, our new service can start, and it can be stopped. All we need to do is define what code should be executed when the service starts, and when the service stops. And if you scroll down a little you will notice that the code already contains place-holder event handlers where we can add whatever code we need:

protected override method OnStart, void
    byval args, [#]String
    endparams
proc
    ;;TODO: Add code to execute when the service is instructed to start
endmethod
		
protected override method OnStop, void
    endparams
proc
    ;;TODO: Add code to execute when the service is instructed to stop
endmethod

Our task is relatively straight forward. All we need to do is add whatever code is necessary to create and expose an instance of a WCF service in the OnStart method, and to stop the service in the OnStop method.

Referencing a WCF Service

The WCF service that we will be hosting has already been created in a separate assembly, so to get access to it we need to add a reference to that assembly in our Windows Service project.

  • In Solution Explorer, right-click on the References folder and from the context menu select Add Reference.
  • Wait for the Add Reference dialog to be displayed and load it’s data, which usually takes a few seconds.
  • Click on the Browse tab, then browse to the location of the assembly that contains your WCF service.
    • If your WCF service is defined in an xfNetLink .NET assembly then this is whatever folder you created the assembly in.
    • If your WCF service is defined in a Synergy .NET Interop project, or some other Visual Studio project, then you will generally find the assembly below that projects “bin” folder.
  • Select the assembly and click the OK button to add the reference to the assembly containing the WCF service.

Additional Steps for xfNetLink .NET WCF Services Only

If your WCF service is defined in an xfNetLink .NET assembly then there are two additional steps that you will need to complete.

Add a reference to xfNetLink .NET

Because your WCF service is defined in an xfNetLink .NET assembly, that assembly will require that your project also has a reference to the xfNetLink .NET assembly.

  • In Solution Explorer, right-click on the References folder and from the context menu select Add Reference.
  • Wait for the Add Reference dialog to be displayed and load it’s data, which usually takes a few seconds.
  • Click on the Browse tab, then browse to the location of the xfNetLink .NET assembly (xfnlnet.dll).
    • The assembly will normally be found under your Program FilesSynergexxfNLNet folder.
  • Select the assembly and click the OK button to add the reference.

Supply xfNetLink .NET Connection Information

Because your WCF service uses xfNetLink (to connect to xfServerPlus in order to execute your Synergy methods), you must tell xfNetLink where the instance of xfServerPlus is listening (host name or IP address, and port number). The best way to do this is via an application configuration (app.config) file.

  • In Solution Explorer, right click on your Windows Service project and from the context menu, select Add > New Item.
  • Select Application Configuration File and click the Add button.

Having added the configuration file to the project you need to specify the required configuration information, something like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="xfnlnet">
      <section name="default" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </sectionGroup>
  </configSections>
  <xfnlnet>
    <default>
      <add key="host" value="192.168.1.10" />
      <add key="port" value="2356" />
    </default>
  </xfnlnet>
</configuration>

Note: You can also use the Synergy .NET Configuration Utility to add this information to the file. Clearly you should replace the IP address and port number with the correct values for your own instance of xfServerPlus.

Hosting an Instance of the WCF Service

In the most basic form, self-hosting a WCF service in another application essentially turns that application into a web server. The web server capabilities are provided by a class in the .NET Framework called ServiceHost. This class is found in a namespace called System.ServiceModel, and is provided the System.ServiceModel.dll assembly.

The code that we’ll be adding will use these web server capabilities to expose a “WCF Endpoint” at a specified HTTP address.

In addition to exposing an endpoint which is an instance of your WCF service, you will usually also want to expose a second “metadata endpoint”. This allows other applications that may need to interact with your WCF service to download the metadata for your service. The metadata fully describes the service and its capabilities, and is made available automatically by WCF. Clients applications can use a standard protocol called Metadata Exchange (often referred to as MEX) in order to download a WCF services metadata from a metadata endpoint. In code, we use a second class called ServiceMetaDataBehavior to expose our services metadata. This class is in the System.ServiceModel.Description namespace, and is also in the System.ServiceModel.dll assembly.

If all of this is starting to sound really complicated, well it is! Luckily the .NET Framework hides most of these requirements from us, and does most of the work. Despite sounding really complicated, the code that we need to write is remarkably simple.

To self host a WCF service there are generally three main things you will need:

  • The URI for the endpoint for the service.
  • An instance of the ServiceHost class to expose your service at that URI
  • An instance of the ServiceMetaDataBehavior class to expose a metadata (MEX) endpoint.

 

So, lets write this thing:

  • Use the Add Reference dialog that you used earlier to add a reference to the Frameworks System.ServiceModel assembly.
  • At the top of the code in your …Service.dbl file, add the following two import statements:
import System.ServiceModel
import System.ServiceModel.Description
  • Somewhere inside the class, but NOT inside any method, add the following data declarations:
private baseAddress ,String
private host        ,@ServiceHost
private smb         ,@ServiceMetadataBehavior

In the procedure division of the OnStart method, add code like this:

protected override method OnStart, void
    byval args, [#]String
    endparams
proc
    ;;Define the URI for the service endpoint
    baseAddress = "http://" + Environment.MachineName + ":8080"

    ;;Create a ServiceHost instance for the WCF service
    host = new ServiceHost(
    &       ^typeof(spc2011.SynergyServer),
    &       new Uri(baseAddress))

    ;;Add a BasicHttp endpoint
    host.AddServiceEndpoint(
    &       ^typeof(spc2011.ISynergyServer),
    &       new BasicHttpBinding(),
    &       "SynergyServer")

    ;;Create a ServiceMetaDataBehavior instance
    smb = new ServiceMetadataBehavior()
    smb.HttpGetEnabled = true
    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15

    ;;Add a MEX endpoint
    host.Description.Behaviors.Add(smb)

    ;;Start the listener
    host.Open()

endmethod

In my example, the namespace in which my WCF service is defined is “spc2011” and the name of the WCF service class is “SynergyServer”. You would need to:

  • Replace the reference to spc2011.SynergyServer with the namespace and class of your WCF service.
  • Replace the reference to spc2011.ISynergyServer with the namespace and interface of your WCF service.

IMPORTANT: When GENCS –W is used to create a WCF service, it applies the ServiceContract attribute to the CLASS that is created, rather than to the INTERFACE. So for xfNetLink .NET WCF services both of the above references should point to the CLASS.

Other than that, the code should work for any WCF service.

Now all that remains it to add the code to stop the WCF service when the Windows service stops. In the procedure division of the OnStop method, add this code:

protected override method OnStop, void
    endparams
proc
    host.Close()
    host.Finalize()
endmethod

Build the Windows Service

It’s time to build the application and see how good your typing is!

  • In Solution Explorer, right-click on your Windows Service project and select Build.
  • Check the output window to make sure your application built correctly. You’re looking for something like this:

 

------ Build started: Project: MyWcfHostService, Configuration: Debug Any CPU ------
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========

If your application does not build correctly then you’ll need to review the instructions above and make sure that you completed the required steps.

Registering and Starting the Windows Service

Now that you have a Windows service there are only two more steps that you’ll need to complete before the service can be tested. Those steps are:

  • Register the service with Windows.
  • Start the service.

To register the service you’ll need to open a Visual Studio command prompt window and then go the the folder that contains your applications executable. This will generally be the binDebug or binRelease folder below your project. Once you’re there you should be able to register your service like this:

..binDebug> INSTALLUTIL MyWcfHostService.exe

Look for messages that indicate that the service was successfully installed, then start your service like this:

..binDebug> NET START MyWcfHostService

Look for messages indicating that the service was started correctly.

Testing the WCF Service

If your Windows service started correctly then your WCF service should now be running. To verify that it is, open a browser and navigate to the URI that was specified in the code.

http://localhost:8080

You should see a WCF service home page similar to this:

image

 

If you see a service page like this then you should be able to start using the service. Of course we haven’t talked about how to do that yet … that’s for another day!

Remember to Stop The Service

You probably want to stop and unregister your Windows Service before you forget that it’s running. To do do, return to the Visual Studio command prompt and use commands like these:

..binDebug> NET STOP MyWcfHostService
..binDebug> INSTALLUTIL /u MyWcfHostService.exe

Exposing WCF services using Synergy .NET Interop

By Steve Ives, Posted on at 11:20 am

In 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:

  1. Building Distributed Apps with Synergy/DE and WCF
  2. Exposing WCF Services using xfNetLink .NET
  3. Hosting WCF Services in an ASP.NET Web Application
  4. Exposing WCF services using Synergy .NET Interop (this post)
  5. Self-Hosting WCF Services
  6. 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:

  1. 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. For more information on this you can refer to a blog post that I wrote back in 2009 called Wave Goodbye to the MDU.
  2. 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.
  3. 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.
  4. 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.

 

image

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.

imageFor 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:

image

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 ==========

 

imageIf 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.


Don't miss a post!

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Recent Posts Tag Cloud Archives