ThingWorx Edge .NET SDK > ThingWorx Edge .NET SDK Reference > .NET SDK: VirtualThing Class > .NET SDK: ServiceDefinition Class
  
.NET SDK: ServiceDefinition Class
Service definitions describe functions that the ThingWorx platform can call on the VirtualThing. A service may have several, or no inputs, and only one result. The most effective and maintainable way to define services is with attributes, as described in the sections below.
The name attribute of a ServiceDefinition and its corresponding method MUST have the same name. Similarly, the name attribute of a ServiceParameter and its corresponding method parameter must have the same name. The examples below illustrate this rule. In the first example, the service called “Add” has the following corresponding method:
[method: ThingworxServiceDefinition(
name="Add",
description="Add two numbers")]
[return: ThingworxServiceResult(
name=CommonPropertyNames.PROP_RESULT,
description="The sum of the two parameters",
baseType=BaseTypes.NUMBER.name())]

public double Add(
[ThingworxServiceParameter(
name="p1",
description="The first addend of the operation",
baseType=BaseTypes.NUMBER.name() )] double p1,

[ThingworxServiceParameter(
name="p2",
description="The second addend of the operation",
baseType=BaseTypes.NUMBER.name() )] double p2)
{
return p1 + p2;
To create a service definition, call the defineService method of the base VirtualThing . There are two defineService methods, one that takes a ServiceDefinition and one that takes the essential parameters of a ServiceDefinition:
defineService(ServiceDefinition serviceDefinition)
defineService(String name, String description,
FieldDefinitionCollection parameterTypes,
FieldDefinition resultType,
AspectCollection aspects)
* 
The examples used in this section should be in the constructor of the extended VirtualThing, or a method called from the constructor. The examples will work as long as the actual service is defined as well, and it should be clear that using the attribute methodology is much cleaner.
ServiceDefinition Attributes
The following properties are available on the ServiceDefinition class:
ThingworxServiceDefinition — Add this to a method to indicate that the ThingWorx platform can use this service.
description — A description of the service.
name — The name of the service.
* 
This must match the name of the method you are defining as a service.
ThingworxServiceResult — Add this to a method to indicate the result of the service.
baseType — The base type of the result. The value of this will be a string value representing the possible base types.
* 
To indicate a void result use the NOTHING base type.
description — A description of the result.
name — A description of the service. The name of the result for the ThingWorx platform, this should always be “result” and there is a constant defined for this: CommonPropertyNames.PROP_RESULT.
ThingworxServiceParameter — Append this to each input parameter.
baseType — The base type of the parameter. The value will be a value of the possible base types.
description — A description of the parameter.
name — Name of the parameter.
* 
The name of the parameter and this name must match.
The example below defines the following:
A new service.
The result of the service.
The parameters used in the service, the operation used for the parameters, and returns the result.
//The following service returns the results of adding two numbers

[method: ThingworxServiceDefinition(
name="Add",
description="Add two numbers")]
[return: ThingworxServiceResult(
name=CommonPropertyNames.PROP_RESULT,
description="The sum of the two parameters",
baseType=BaseTypes.NUMBER.name())]

public double Add(
[ThingworxServiceParameter(
name="p1",
description="The first addend of the operation",
baseType=BaseTypes.NUMBER.name() )] double p1,

[ThingworxServiceParameter(
name="p2",
description="The second addend of the operation",
baseType=BaseTypes.NUMBER.name() )] double p2)
{
return p1 + p2;
}
The example below defines the following:
A new service.
The result of the service.
A function that obtains the expected data, and returns the result.
//The following service returns the current date and time

[method: ThingworxServiceDefinition(
name="WhatTimeIsIt",
description="Returns the current time")]
[return: ThingworxServiceResult(
name= CommonPropertyNames.PROP_RESULT,
description="",
baseType=BaseTypes.DATETIME.name())]

public DateTime WhatTimeIsIt() {
return DateTime.Now;
}
The example below does the following:
Defines a new service that takes no parameters.
Defines the result of the service.
Performs an arbitrary function that returns nothing.
//The following function takes no parameters and returns nothing

[method: ThingworxServiceDefinition(
name="SimpleService",
description="Returns nothing")]

[ThingworxServiceResult(
name=CommonPropertyNames.PROP_RESULT,
description="",
baseType=BaseTypes.NOTHING.name())]

public void SimpleService() {
//Do something here...
}
The example below defines the following:
A new service.
The fields used in the service.
The result of the service.
The operation used for the fields, and returns the result.
//Put this code in the constructor (or a method called
from the constructor)
//
ServiceDefinition serviceDef = new ServiceDefinition(
"Add",
"Add two numbers");

FieldDefinitionCollection parameterFields = new FieldDefinitionCollection();
parameterFields.addFieldDefinition(
new FieldDefinition(
"p1",
"The first addend of the operation",
BaseTypes.NUMBER)
);

parameterFields.addFieldDefinition(
new FieldDefinition(
"p2",
"The second addend of the operation",
BaseTypes.NUMBER)
);

FieldDefinition resultField = new FieldDefinition(
CommonPropertyNames.PROP_RESULT,
"The sum of the two parameters",
BaseTypes.NUMBER);

serviceDef.setParameters(parameterFields);

serviceDef.setResultType(resultField);
base.defineService(serviceDef);

The implementation of the ServiceDefinition will be just like any other method that is defined on the extended VirtualThing:
//Actual service definition

public Double Add(Double p1, Double p2)
{
return p1 + p2;
}
The processServiceRequest of the VirtualThing will need to be overridden in the extended VirtualThing to check the name of the incoming ServiceDefinition and call the appropriate method. There is no need to call the processServiceRequest of the VirtualThing since it only throws an exception.