Defining a base service in a library

Using VS2022, C# 10, RO 10, .Net Framework 4.8, code first

I’ve defined a base server class that allows me to provide my servers with some basic functionality: consistent logins, heartbeats, machine information, etc. The interfaces define methods and events and they work with zero application code necessary, which is my goal. The server side works well. All of this code goes into an assembly I can share among my servers.

My problem comes in with the client side. Is there any reasonable way to manage the access to the base services in a client assembly? I’m struggling to find a way to do this without it being a maintenance nightmare.

Can anyone give me suggestions, or point to an example? If so, I’d greatly appreciate it.

Hello

Could you describe in more details (example maybe) what exactly you want to achieve?

Regards

Background: Most of my work is in specialized industrial automation and such so connectivity and status are important debug tools in the field. Many of our existing (non RO applications) connect to multiple pieces of industrial hardware via disparate communication methods (that we do not get to choose). This is our first major .Net project and I’m looking to break individual hardware talking ‘modules’ into separate standalone (RO server) applications, to hopefully be able to reuse more of the modules in multiple projects. The other desired benefit is with the project broken in to individual modules we can easily make portions of it run as a service. I expect this particular project to 5+ servers (a traffic cop/process controller and 4+ pieces of hardware) and at least one client, which will likely be the only user facing application. The servers could be run on the same physical machine or sometimes be split up and though theoretically multiple users could connect to the traffic cop/process controller (via the client), that won’t be a common situation.

I’m looking to be able to have my servers provide a base level of functionality to every client that
connects to them. Some status things like: uptime, application version, configuration, etc. The idea would be for the client be able to display that in a coherent fashion on some window (tabbed likely, with one tab per server) so an operator can pop through the tabs and get a details status report of each server and it’s state.

So, I can easily define a common (base) service that each server’s main service would inherit from, and those capabilities are then available to any client connecting, without my having to go through any specific effort on the server (i.e. write it once, pop it in a C# class library and I’m ‘done’). The server side could consist of just code being called when the client makes a request and/or several threads that would automatically be created in the server to collect and collate information and then pass that back to clients via events.

My problem comes in from the client side. If I have an event sink called IStatusSink defined in my class library and then correspondingly made available in all my server applications, it appears I need to connect the client to each server independently and generate *_intf.cs files for each, and each server’s _intf.cs would contain it’s own reference to it’s own (essentially) IStatusSink, in it’s own namespace. This would preclude me from writing common code on the client to accept an event call from any server, depending on which channel I connected to an object. Or at least, it seems like it would, since the call to RegisterEventHandler requires a typeof(‘event sink interface’) parameter. Similar problems seem to exist for method calls.

It would seem like I could make a dummy server application that contained just the base services/event sinks and import that into the client, but it’s unclear whether those interfaces generated into their own _intf.cs would be usable as a basis for writing common code that could handle them all.

Am I missing something simple/stupid? Is this just not possible and I need to write boilerplate in each client application, rather than common code? Is there some other mechanism to handle this type of situation that I’m just looking past? Any comments/suggested would be welcomed.

Hopefully I’ve explained the situation clearly enough.

Hi,

I think, it is better suitable the RODL-based service for your case. it allows to create and use shared RODL in other services.
We use similar behavior in Data Abstract product - it has the base RODL (DataAbstract.RODL) that contains declarations of services, events, enums and types:


You can convert your CodeFirst service to RODL-based service with Service Builder:

  • launch your CodeFirst Server
  • launch Service Builder
  • Edit->Import->Import Remoting SDK service (RODL) …
  • after import, you can generate Interface file that will contain all your declarations

Hello

Thew will. If all your servers share the same API interface then the same proxy classes (ie the _Intf file) can be used for all of them.

From the technical point of view structures, event sink and service method names etc are identified by their ‘short’ names (name of the class/interface only, without the namespace name)

Regards