Can a code first service be built dynamically?

I am interested in building a system where an end user can design services / functions dynamically for integration with other software. Therefore the methods provided by the service would not be known when the server application is being built. The methods would then call scripts to perform the desired functionality.

Is this possible?
Do you have any examples?

.NET ot Delphi?

I would be using .NET / C#

Hello

For statically built assemblies containing service classes it would be enough just to load them into application.

For dynamic services the task might be a bit more difficult. I am currently working on a prototype that would allow this.

I started looking into CodeDOM a bit this weekend to see if this would be a viable solution.

Yes, that would work too. However you’d have to regenerate code after each change in the service interface.

So here is an example of a dynamic code-first service:
ModularServerTest2.zip (12.9 KB)

Solution contains 2 projects:

  1. ModularServerTest2 is a server application. It does not define any services.
    Take a look at the Program.cs code (namely method LoadExternalAssemblies)
    This method loads an assembly from a file (you’d need to change the path here to match the one you use), scans its public types for a class named Startup and then executes a method RegisterServices defined in this class.
  2. ServiceLibrary is the class library containing service definition.
    First, the Startup class.
    Its RegisterServices method contains this code:
            var rodlProvider = new RodlProvider();
            rodlProvider.LoadConfiguration(); // In this method the RODL provider should load the service metainformation somehow, f.e. via some script

            // Register RODL info provider
            RemObjects.SDK.Server.RodlResource.RegisterRodlProvider(rodlProvider);

            // Register Service invoker(s)
            RemObjects.SDK.Server.Engine.ServiceManager.RegisterService("DynamicService", typeof(DynamicServiceActivator), new DynamicServiceActivator(), new DynamicServiceInvoker("DynamicRodlLibrary", "DynamicService", rodlProvider.GetServiceMethodDefinitions()));

Actually it loads service configuration (more on this later) and registers this configuration in server metainformation provider (aka RODL). Then it registers the service itself. The DynamicServiceInvoker created here is the heart of this dynamic service.

The DynamicServiceActivator class is just a dummy that does nothing. Its CreateInstance method implementation depends on your concrete implementation of script management code.

The RodlProvider class should gather dynamic service API (ie methods defined in the scripts) and turn it into a RODL definition code and a list of method definitions.
Currently this class contains hard-coded definitions of 2 methods.

The DynamicServiceInvoker class is the heard of this dynamic service. Its ServiceMethodInvoker method id invoked by Remoting SDK every time when server wants to execute a service method.

You will need to replace this console logging code with actual call to your script:

			// TODO Invoke your script here. For now it is replaced with Console calls
			{
                Console.WriteLine($"Service: {message.InterfaceName}");
				Console.WriteLine($"Method: {methodName}");
                Console.WriteLine($"Parameters: {parameterValues.Length}");
				for (Int32 i = 0; i < parameterValues.Length; i++)
                {
                    Console.WriteLine($"{i}: {parameterValues[i]}");
                }
				

			}
			// Fake result value instead of a real call
			object result = "Dynamic method result";

Hope that helps