Description
In this post I will show you how to create a simple WCF SOAP Service and consume it from Dynamo. These kind of services can be deployed on a server machine and be consumed by multiple dynamo users. You can design your most complicated algorithms and use a powerful machine to make the calculations then return the result to dynamo.
According to Microsoft WCF (Windows Communication Foundation) is a framework for building service-oriented applications. Using WCF, you can send data as asynchronous messages from one service endpoint to another.
WCF is designed using service-oriented architecture principles to support distributed computing where services have remote consumers. Clients can consume multiple services; services can be consumed by multiple clients.Services typically have a WSDL interface (Web Services Description Language) that any WCF client can use to consume the service, regardless of which platform the service is hosted on.
With WCF you can design both Simple Object Access Protocol (SOAP) and Representational State Transfer (REST) applications.
I will not go into details about SOAP vs Rest applications but the idea is that both provide web services, which are basically computations deployed on a different machine and requested by a client machine.
Creating a WCF Service
To create a WCF service you can simply create a new WCF Service project and define the contracts.


Let’s start by defining a Point class called SvcPoint (we cannot directly reference Dynamo packages and use Point because it’s not serializable).
And for this service we will provide 2 operations:
- A method that returns the sum of 2 numbers
- A method that returns the sum of 2 points
[DataContract] public class SvcPoint { private double x; [DataMember] public double X { get { return x; } set { x = value; } } private double y; [DataMember] public double Y { get { return y; } set { y = value; } } private double z; [DataMember] public double Z { get { return z; } set { z = value; } } public SvcPoint(double x, double y, double z) { this.X = x; this.Y = y; this.Z = z; } }
[ServiceContract] public interface IService { [OperationContract] double Sum(double value1, double value2); [OperationContract] SvcPoint Add(SvcPoint pt1, SvcPoint pt2); }
public class Service : IService { public SvcPoint Add(SvcPoint pt1, SvcPoint pt2) { return new SvcPoint(pt1.X + pt2.X, pt1.Y + pt2.Y, pt1.Z + pt2.Z); } public double Sum(double value1, double value2) { return value1 + value2; } }
To deploy the service you can simply press F5 key and the browser will popup with the service adress. Remember that this is a webservice, meaning that it’s consumed over the internet using a WDSL protocol (XML structure).


Testing the service
To test this service I’ve created a console application. Now to reference the service right click the solution and click “Add Service Reference”




After adding the service reference (you have to paste in the http of the service), you can simply create a new object if type IService and call the methods you defined.
class Program { static void Main(string[] args) { IService service = new ServiceClient(); Console.WriteLine(service.Sum(2, 3)); } }
Consuming the service in DynamoBIM
In dynamo we cannot simply reference the service and create a new instance, it’s a WCF issue where class is loaded in another running application and therefore it cannot find the endpoint. But we can programatically create a communication channel and .NET makes that pretty easy.
To create this package we will make 2 solutions. In one in which we reference the service and from NuGet we add DynamoCore libraries. In the other we create the package methods. In this way we prevent some methods or interface definitions from the imported libraries to appear in Dynamo.
NOTE : Make sure that in the solution containing the Dynamo methods you don’t reference the service (instead reference the solution referencing the service) otherwise Dynamo will add some methods in the UI that it grabs from the referenced service


The code in the BLL class that defines the channel factory (communication with the service) and the client methods that consume the methods:
public static class ServiceMethods { // Object used to lock multi-threaded access to same property. private static object mThreadLock = new object(); private static ChannelFactory mSvcChannelFactory; // A ChannelFactory object that references methods defined in our service. private static ChannelFactory SvcChannelFactory { //Lazy binding our object. get { lock (mThreadLock) { if (mSvcChannelFactory == null) { //Normally we would create by new-ing the service. //ServiceClient serviceClient = new ServiceClient(""); var myBinding = new BasicHttpBinding(); var myEndpoint = new EndpointAddress("http://localhost:59024/Service.svc"); mSvcChannelFactory = new ChannelFactory(myBinding, myEndpoint); } } return mSvcChannelFactory; } } private static IService mServiceRef; private static IService ServiceRef { get { if (mServiceRef == null) { mServiceRef = SvcChannelFactory.CreateChannel(); } return mServiceRef; } } public static double BllSum(double v1, double v2) { double sum = ServiceRef.Sum(v1, v2); ((ICommunicationObject)ServiceRef).Close(); return sum; } public static Point BllAddPoints(Point p1, Point p2) { SvcPoint svcp1 = new SvcPoint { X = p1.X, Y = p1.Y, Z = p1.Z }; SvcPoint svcp2 = new SvcPoint { X = p2.X, Y = p2.Y, Z = p2.Z }; SvcPoint sumPoint = ServiceRef.Add(svcp1, svcp2); var p = Point.ByCoordinates(sumPoint.X, sumPoint.Y, sumPoint.Z); ((ICommunicationObject)ServiceRef).Close(); return p; } }
Dynamo Nodes
The dynamo related code that uses BLL code to access the service methods:
public static class ServicePkg { [MultiReturn(new[] { "Result" })] public static Dictionary<string, double> SumFromService(double value1, double value2) { return new Dictionary<string, double> { {"Result", BLL.ServiceMethods.BllSum(value1, value2) } }; } [MultiReturn(new[] { "Result" })] public static Dictionary<string, Point> AddPoints(Point p1, Point p2) { return new Dictionary<string, Point> { { "Result", BLL.ServiceMethods.BllAddPoints(p1, p2)} }; } }

