--- applyTo: "Fuchs_DataService/**" --- # Fuchs_DataService Instructions ## Overview `Fuchs_DataService` is a .NET 10 Windows Service (via **Topshelf**) that synchronises MFR entity data into the Fuchs SQL database on a configurable schedule. ## Key Classes | Class | Role | |-------|------| | `FdsMainModule` | Entry point — builds `LoggerFactory`, creates `FdsService`, runs Topshelf | | `FdsService` | Topshelf `ServiceControl` — owns `PeriodicHostedService` lifecycle | | `PeriodicHostedService` | Runs one or more `PeriodicJobDefinition` jobs independently | | `FdsMfr : IFdsMfr` | Singleton business logic — registered via DI constructor injection | | `FdsMfrClient` | Wraps `MFRClient` + SQL write logic; instantiated per-use inside `FdsMfr` | | `Archive` (FdsZip) | SevenZip wrapper; created per-use, accepts optional `ILogger` | | `FdsConfig` | Static config accessor — reads from `appsettings.json` under `Fds:` key | | `FdsShared` | Static SQL/stream helpers — use `FdsDebug.DebugLog` for errors in static methods | | `FdsDebug` | Legacy static logger — **only for use in static helper methods** | | `FdsLoggerProvider` | Custom `ILoggerProvider`: Debug output + file + prepared DB logging | ## Dependency Injection `FdsMfr` is the main business singleton. It receives: - `ILogger` — for its own logging - `ILoggerFactory` — to create loggers for `FdsMfrClient` and `Archive` it instantiates ```csharp // FdsService constructor var mfr = new FdsMfr(loggerFactory.CreateLogger(), loggerFactory); ``` ## Configuration (`appsettings.json`) ```json { "ConnectionStrings": { "fuchs_fds_ConnectionString": "...", "fuchs_ConnectionString": "..." }, "Fds": { "ExecutionFrequency_Minutes": 15, "DebugDetails": false, "MFR_UserName": "...", "MFR_Password": "...", "MFR_host": "https://..." } } ``` ## Rules - Do **not** use `System.Configuration.ConfigurationManager` — always use `FdsConfig` / `IConfiguration`. - Do **not** use `OCMS` or `OCMS_sharp`. - Use `FdsSqlOptions` for all SQL calls (`getSQLDatatable_async`, `getSQLDataSet_async`, `setSQLValue_async`). - Classes that run async work must use `async/await` — never `.Wait()` or `.Result` in new code. - Add new periodic jobs as `PeriodicJobDefinition` entries in `FdsService` — see `periodic_service.instructions.md`. - Logging: see `logging.instructions.md`.