"No connection manager has yet been registered" error because Engine.Load is not being called

Hello,

I just upgraded a solution from VS 2015 and O/DA 9.0.97 to VS 2017 and 9.6.113. And when I try to run a query against the application server, I’m getting the error “No connection manager has yet been registered”. I tracked the problem down to the RemObjects.DataAbstract.Server.Engine.Load method not being called. If I add the line:

RemObjects.DataAbstract.Server.Engine.Load();

the project works fine, but I wanted to know what am I missing that this is not being called, as it was in VS2015/DA9.0.97. After some debugging, I see that in the 9.0.97 project, this code is called twice:

namespace RemObjects.SDK.Server
{
	sealed class ConfigurationLoader
	{
		public void Load()
		{
			...
			foreach (Type type in ReflectionHelpers.GetExportedTypes(assembly))
			{
				...
				if (!lConfiguration.IsLoaded)
				{
					lConfiguration.Load(this.fApplicationName, this.fRodlNamespace);
				}...
			}
		}
	}
}

and the second time it is called, the Engine.Load method is called. This is not happening in the upgraded project. Unfortunately, I cannot see the details of the types or assemblies being loaded during the debugging process, so I need some help figuring this out, :slight_smile:.

Thanks,
Arturo.

Hello

Interesting. This method is intended to called only once during the server startup, not twice. Could you show the Program.Main method code?

Btw are your service classes defined in the same assembly/project as the Program.Main entry point or they live in separate projects?

Hello, Antonk,

This is the code I’m using in Program.Main:

namespace FinanzaPro.ApplicationServer
{
	static class Program
	{
		[STAThread]
		public static int Main(String[] args)
		{
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

			RemObjects.SDK.Server.ApplicationServer server = 
                new RemObjects.SDK.Server.ApplicationServer(...);
			
			server.Run(args);
			return 0;
		}
	}
}

The code that is called twice is:

lConfiguration.Load(this.fApplicationName, this.fRodlNamespace);

not the ConfigurationLoader.Load() method. After doing some more digging, I see that in the VS2015 project, it is being called for RemObjects.SDK.Server.Configuration and RemObjects.DataAbstract.Server.Engine, which are the two classes with the [ServerConfiguration] attribute.

But in the new project, it is being called only for the RemObjects.SDK.Server.Configuration class, even though the project references the RemObjects.DataAbstract.Server assembly.

And the DA services are in the same project, and RemObjects.DataAbstract.Server is being used there.

Thanks,
Arturo

That’s odd. Could you sent to support@ your project? Both source code AND compiled project. If you don’t want to disclose them then you can comment out all business logic and even the Schema / Connection files, because this happens way before they are loaded.

Ok, done. Just sent a minimum version of the project, which displays this behaviour in VS2017.

I think the problem is here:

Assembly[] lDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies();

The RemObjects.DataAbstract.Server assembly is not being loaded here, so presumably, according to the StackOverflow answer below, it is not being used anywhere before loading the configurations:

If I create a dummy DataAbstract service instance before the server.Run(args) line, the Engine.Load method is called correctly.

Thanks,
Arturo

Thanks for the testcase. Odd this that is does NOT fail for me, but I see now what can cause this issue.

Yes, this lazy assembly loading and issues caused by it are a known thing in the .NET world. I’ll add additional references warm-up code so this issue’s cause will be gone.

For now, you can do the following thing to ensure that references are loaded (instead of “creating a dummy DataAbstract service instance”):

Modify your ApplicationServer constructor call by adding typeof(YourDataService) as its last parameter, so it will look like

        RemObjects.SDK.Server.ApplicationServer server = new RemObjects.SDK.Server.ApplicationServer(
                                                             "..REDACTED..",
                                                             "..REDACTED..",
                                                             "..REDACTED..",
                                                             "..REDACTED..",
                                                             typeof(YourDataService));

(I’ve redacted actual string values and the real class name just in case)

This typeof call will ensure that the DataService type and all its references are being loaded during the constructor call.

Note: This approach (ie adding typeof parameter(s)) also works in the case of services defined in assemblies other than the assembly containing the Program.Main entry point. Mean, one can define services in separate projects, but in this case he will have to explicitly mention their implementations in the ApplicationServer constructor call.

Sorry for the inconvenience

Thanks, logged as bugs://82453

Perfect! I added the line you suggested and Engine.Load is now being called.

Thanks!

bugs://82453 got closed with status fixed.