Skip to main content
Skip table of contents

Server-Side C# Mapping for Interfaces

Skeleton Classes

On the server side, interfaces map to skeleton classes. A skeleton is a class that has an abstract method for each operation on the corresponding interface. For example, consider our Slice definition for the Node interface:

SLICE
module VisitorCenter
{
    interface Greeter
    {
        ["cs:identifier:Greet"]
        string greet(string name);
    }
}

The Slice compiler generates the following definitions for this interface:

C#
namespace VisitorCenter
{
    public partial interface Greeter : Ice.Object
    {
        string Greet(string name, Ice.Current current);
    }

    public abstract partial class GreeterDisp_ : Greeter
    {
        public abstract string Greet(string name, Ice.Current current);

        public ValueTask<Ice.OutgoingResponse> dispatchAsync(
            Ice.IncomingRequest request)
        {
            ...
        }
    }

    public partial interface AsyncGreeter : Ice.Object
    {
        Task<string> GreetAsync(string name, Ice.Current current);
    }

    public abstract partial class AsyncGreeterDisp_ : AsyncGreeter
    {
        public abstract Task<string> GreetAsync(string name, Ice.Current current);

        public ValueTask<Ice.OutgoingResponse> dispatchAsync(
            Ice.IncomingRequest request)
        {
            ...
        }
    }
}

The important points to note here are:

  • As for the client side, Slice modules are mapped to C# namespaces with the same name, so the skeleton class definitions are part of the VisitorCenter namespace.

  • For each Slice interface, the compiler generates two C# interfaces and two C# classes - the skeleton interfaces and classes.

  • Each skeleton class contains an abstract method for each operation in the Slice interface.

  • Each skeleton class implements the dispatchAsyncmethod provided by Ice.Object: it dispatches incoming requests to the methods on the skeleton class based on the operation name received in the request.

Ice.Object Servant Base Interface

The Slice pseudo-interface Object is mapped to the Ice.Object interface in C#:

C#
namespace Ice
{
    public interface Object
    {
          public ValueTask<OutgoingResponse> dispatchAsync(IncomingRequest request)
          { 
              ...
          }
          ...
    }
}

Ice.Object provides a default dispatchAsync implementation for the 4 operations on the Slice pseudo-interface Object: ice_ping, ice_isA, ice_id and ice_ids.

Servant Classes

In order to provide an implementation for an Ice object, you must create a servant class that inherits from one of the generated skeleton classes. For example, to create a servant for the Greeter interface, you could write:

C#
public class Chatbot : VisitorCenter.GreeterDisp_ 
{
    public override string Greet(string name, Ice.Current current) =>
        $"Hello, {name}!";
}

Note that Chatbot inherits from VisitorCenter.GreeterDisp_, one of the two skeleton classes.

As far as Ice is concerned, the Chatbot class must implement only a single method: the abstract method Name that it inherits from the skeleton class. This makes the servant class a concrete class that you can instantiate. You can add other methods and fields as you see fit to support your implementation.

The async skeleton class is described in Asynchronous Method Dispatch (AMD) in C#.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.