Code-First Servers

Code-First Servers are one of the big new features in RemObjects SDK 9, and they drastically improve the ease with which you can both create and maintain/update your server projects, without relying on manually editing the .RODL in Service Builder.

Code-First servers are the preferred and recommended mode when you start a new server project with Remoting SDK 9 or later, and we recommend converting your existing servers to Code-First if you can (although that is not a requirement for updating Remoting SDK 9, and classic RODL-based server projects will continue to be supported indefinitely).

What is “Code First”?

In the past, if you created a new RemObjects SDK server, you started with a .RODL file, and would edit that in Service Builder to define all the services and the types that the services worked with. Behind the scenes, Remoting SDK would then generate code and stub classes for your service implementation for you.

While this mode of creating servers will of course continue to be supported, Code-First mode does away with RODL files completely — at least on the server — and lets you define everything purely in code.

You simply define your service classes and attach a couple of attributes to make them available remotely, and Remoting SDK will take care of the rest and make sure they become callable. Similarly, any auxiliary types you define – enums, structs, etc. – you can simply define (and update) in code.

At runtime, Remoting SDK will generate a RODL representation of your services based on the types it finds in your app and make that available to download for clients and IDEs (see Connecting to a Remoting SDK Server for details). So to the outside, a Code-First server looks identical to a traditional RODL-based server, and for use on the client, you can still import the (now auto-generated) RODL from your IDE or the codegen tool to generate client Interface stubs.

Let’s take a look at how this works in practice.

Attribute-Based Services, Defined in Code

Code-First servers rely on two simple attributes to mark services for publication. Simply create a class descending from RemObjects.SDK.Server.Service (.NET) or TRORemoteDataModule (Delphi) and attach these attributes to mark your service class as being available for clients to call into:

[Service, StandardClassFactory]
public class MyService : Service
{
    [ServiceMethod]
    public string DoSomethingCool()
    {
        // Do something cool
    }
}
type
  [Service, StandardClassFactory]
  MyService = public class(Service)
  public
    [ServiceMethod]
    method DoSomethingCool: String;
  end;
@Service @StandardClassFactory public class MyService : Service {
    @ServiceMethod public func DoSomethingCool() -> String {
        // Do something cool
    }
}
<Service> <StandardClassFactory> _
Public Class MyService
    Inherits Service

    &lt;ServiceMethod> _
    Public Function DoSomethingCool() As String
        ' Do something cool
    End Function

End Class
type
 [ROService]
  TMyService = class(TRORemoteDataModule)
  public
    [ROServiceMethod]
    function DoSomethingCool(): String;
  end;

The Service (.NET) or ROService (Delphi) attribute is used on the class itself, to indicate that it is a remotable service. Each method you want to publish is then simply marked with ServiceMethod (.NET) or ROServiceMethod (Delphi), to distinguish it from any internal methods you want to keep internal to the server.

And that's it, Remoting SDK will automatically make this class available to clients.

Additional attributes are available to optionally configure your service. For example, you can specify what class factory to use (StandardClassFactory is the default, and does not need to be specified), or you can use ServiceRequiresLogin (.NET) or ROServiceRequiresLogin (Delphi) to make a service as only being callable if the client authenticated before (see the Authentication and Login topic for details).

Converting Existing Servers

If you have an existing RODL-based server, you can easily convert this server to the new Code-First model with a few simple steps:

Documentation

On .NET, you can use the DocumentationAttribute or DescriptionAttribute (from the standard System.ComponentModel namespace), to add descriptions to your services and methods that will become part of the documentation in the RODL.

On Delphi, the [RODocumentation('...')] attribute can be used for the same effect.