TXTextControl.DocumentServices.Plugin.Abstractions
5.0.1
Prefix Reserved
dotnet add package TXTextControl.DocumentServices.Plugin.Abstractions --version 5.0.1
NuGet\Install-Package TXTextControl.DocumentServices.Plugin.Abstractions -Version 5.0.1
<PackageReference Include="TXTextControl.DocumentServices.Plugin.Abstractions" Version="5.0.1" />
<PackageVersion Include="TXTextControl.DocumentServices.Plugin.Abstractions" Version="5.0.1" />
<PackageReference Include="TXTextControl.DocumentServices.Plugin.Abstractions" />
paket add TXTextControl.DocumentServices.Plugin.Abstractions --version 5.0.1
#r "nuget: TXTextControl.DocumentServices.Plugin.Abstractions, 5.0.1"
#:package TXTextControl.DocumentServices.Plugin.Abstractions@5.0.1
#addin nuget:?package=TXTextControl.DocumentServices.Plugin.Abstractions&version=5.0.1
#tool nuget:?package=TXTextControl.DocumentServices.Plugin.Abstractions&version=5.0.1
TXTextControl.DocumentServices.Plugin.Abstractions
TXTextControl.DocumentServices.Plugin.Abstractions defines the shared interface and plugin lifecycle for building external plugin assemblies that extend the functionality of Text Control DS Server.
This package allows developers to build .dll plugins that:
- Register custom ASP.NET Core API controllers
- Add middleware or route handlers
- Access DS Server configuration and services via Dependency Injection (DI)
- Execute startup/shutdown logic
✨ Features
- Controller-based plugins: Add custom API endpoints
- Lifecycle hooks: Initialize and clean up plugin logic
- Service registration: Register your own services into the DI container
- Dependency Injection access: Use built-in DS Server services such as
IDocumentProcessingServiceorIDocumentEditorSessionService - Middleware support: Add request interceptors, metrics, logging, etc.
📦 NuGet
dotnet add package TXTextControl.DocumentServices.Plugin.Abstractions
If you want to see a complete plugin implementation, refer to the TXTextControl.DocumentServices.SamplePlugin example project, which demonstrates how to use this package in a real DS Server plugin.
1️⃣ Basic Plugin Structure
📜 Interface Overview
namespace TXTextControl.DocumentServices.Plugin.Abstractions;
public interface IPlugin {
string Name { get; }
string Description { get; }
string Version { get; }
string UIBasePath => null; // Optional, for plugins with a web UI (e. g. /plugin-ui/config)
void ConfigureServices(IServiceCollection services, PluginContext context) { }
void ConfigureMiddleware(WebApplication app, PluginContext context) { }
void OnStart(IServiceProvider services, PluginContext context) { }
void OnStop() { }
}
PluginContext provides metadata about the DS Server environment:
public class PluginContext {
public string DsServerVersion { get; set; } = default!;
public string BaseDirectory { get; set; } = default!;
public IConfiguration Configuration { get; set; } = default!;
}
🚀 Getting Started
To create a basic plugin with a controller and custom middleware, follow these steps:
1. Create a new class library project
dotnet new classlib -n MyFirstPlugin
cd MyFirstPlugin
2. Add the abstraction package
dotnet add package TXTextControl.DocumentServices.Plugin.Abstractions
3. Define a service to hold config state
public class GreetingState {
public string Greeting { get; set; } = "Hello (default)";
}
4. Create a controller
This controller will respond to requests at /plugin/hello:
using Microsoft.AspNetCore.Mvc;
namespace MyFirstPlugin;
[ApiController]
[Route("plugin/[controller]")]
public class HelloController : ControllerBase {
private readonly GreetingState m_state;
public HelloController(GreetingState state) {
m_state = state;
}
[HttpGet]
public string Get() => m_state.Greeting;
}
5. Implement the plugin class
This class implements the IPlugin interface, reads the greeting text from the configuration and registers a middleware to log requests:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TXTextControl.DocumentServices.Plugin.Abstractions;
namespace MyFirstPlugin;
public class HelloPlugin : IPlugin {
public string Name => "MyFirstPlugin";
public string Description => "Adds a /plugin/hello endpoint and logs requests.";
public string Version => "1.0.0";
public void ConfigureServices(IServiceCollection services, PluginContext context) {
// Retrieve the greeting from the configuration and register it as a singleton service.
// This is just an example. Implementing ConfigureServices is optional.
var greeting = context.Configuration["MyFirstPlugin:Greeting"] ?? "Hello (default)";
services.AddSingleton(new GreetingState { Greeting = greeting });
}
public void ConfigureMiddleware(WebApplication app, PluginContext context) {
// Register a middleware to log requests to the /plugin/hello endpoint.
// This is also just an example. Implementing ConfigureMiddleware is optional.
app.Use(async (ctx, next) => {
if (ctx.Request.Path.StartsWithSegments("/plugin/hello")) {
var logger = ctx.RequestServices.GetRequiredService<ILogger<HelloPlugin>>();
logger.LogInformation("MyFirstPlugin intercepted request to /plugin/hello");
}
await next();
});
}
public void OnStart(IServiceProvider services, PluginContext context) {
// This method is called when the plugin is started. You can use this to
// initialize resources or perform startup logic. Implementing OnStart is optional.
var logger = services.GetService<ILogger<HelloPlugin>>();
var state = services.GetService<GreetingState>();
logger?.LogInformation("Plugin started. Greeting: {Greeting}", state?.Greeting);
}
public void OnStop() {
// Cleanup logic if needed. This is also optional.
}
}
6. Optional plugin settings
If your plugin expects config settings, add them to appsettings.json:
"MyFirstPlugin": {
"Greeting": "Howdy from DS Server!"
}
7. Deploy and test the plugin
Build your plugin:
dotnet buildCreate a subfolder inside the
Plugins/directory of your DS Server installation (e.g.Plugins/SamplePlugin/)Copy the resulting
.dllfile (e.g.bin/Debug/net10.0/MyFirstPlugin.dll) into that subfolder:Plugins/ └── SamplePlugin/ └── MyFirstPlugin.dllRestart DS Server.
Access the endpoint:
GET http://<your-server>/plugin/hello
2️⃣ Accessing DS Server Services via Dependency Injection
Starting with DS Server v5.0, several core services are exposed to plugins through Dependency Injection (DI).
These can be injected into controllers, services, or middleware. Typical use cases include:
- Converting and merging documents
- Manipulating or querying live Document Editor sessions
- Generating barcodes or analyzing PDF forms
2.1 IDocumentProcessingService
Provides access to all document processing capabilities of DS Server.
Example: Convert and Merge Documents, extract PDF form fields and generate barcodes in a plugin controller
using Microsoft.AspNetCore.Mvc;
using TXTextControl.DocumentServices.DocumentProcessing.Abstractions;
using TXTextControl.DocumentServices.DocumentProcessing.Models;
[ApiController]
[Route("plugin/[controller]/[action]")]
public class DocumentProcessingController : ControllerBase {
private readonly IDocumentProcessingService m_processing;
public DocumentProcessingController(IDocumentProcessingService processing) {
m_processing = processing;
}
[HttpPost]
public async Task<IActionResult> Convert([FromBody] byte[] document, [FromQuery] string format = "PDF") {
ReturnFormat returnFormat = Enum.Parse<ReturnFormat>(format, true);
byte[] result = await m_processing.ConvertAsync(document, returnFormat, true);
return returnFormat switch {
ReturnFormat.PDF => File(result, "application/pdf", "converted.pdf"),
ReturnFormat.HTML => File(result, "text/html", "converted.html"),
ReturnFormat.DOCX => File(result, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "converted.docx"),
ReturnFormat.RTF => File(result, "application/rtf", "converted.rtf"),
_ => File(result, "application/octet-stream", "converted.dat"),
};
}
[HttpPost]
public async Task<IActionResult> MergeExample([FromBody] byte[] template) {
MergeBody mergeBody = new() {
Template = template,
MergeData = new[] {
new { Name = "Alice" },
new { Name = "Bob" }
}
};
byte[][] merged = await m_processing.MergeAsync(mergeBody, ReturnFormat.PDF, append: true);
return File(merged[0], "application/pdf", "merged.pdf");
}
[HttpPost]
public async Task<IActionResult> GetAcroFormFields([FromBody] byte[] pdfDocument) {
FormField[] formFields = await m_processing.PDF.AcroForms.GetFieldsAsync(pdfDocument);
return Ok(formFields);
}
[HttpGet]
public async Task<IActionResult> CreateBarcode([FromQuery] string text = "https://www.textcontrol.com") {
byte[] image = await m_processing.Barcodes.CreateAsync(new BarcodeSettings(text));
string base64 = System.Convert.ToBase64String(image);
return Ok(new { ImageDataUrl = $"data:image/png;base64,{base64}" });
}
}
Common Operations
| Operation | Method | Description |
|---|---|---|
| Merge | MergeAsync |
Mail merge using JSON or object data |
| Convert | ConvertAsync |
Convert between document formats |
| Find/Replace | FindAndReplaceAsync |
Replace text |
| Append | AppendAsync |
Combine multiple documents |
| Thumbnails | GetThumbnailsAsync |
Generate image previews |
| Document Info | GetDocumentInfoAsync |
Extract metadata and merge fields |
Sub-APIs
| API | Interface | Description |
|---|---|---|
IPdfApi |
Create PDFs, extract metadata, embedded files | |
| AcroForms | IAcroFormsApi |
Read and analyze PDF form fields |
| Barcodes | IBarcodesApi |
Generate and validate barcode images |
2.2 IDocumentEditorSessionService
Provides access to active Document Editor sessions managed by DS Server.
This allows you to manipulate open documents, retrieve fields, or change formatting in real time.
Example: Working with Sessions
using Microsoft.AspNetCore.Mvc;
using TXTextControl.DocumentServices.DocumentEditor.Abstractions;
using TXTextControl.DocumentServices.DocumentEditor.Enums;
using TXTextControl.DocumentServices.DocumentEditor.Options;
[ApiController]
[Route("plugin/[controller]/[action]")]
public class DocumentEditorController : ControllerBase {
private readonly IDocumentEditorSessionService m_sessions;
public DocumentEditorController(IDocumentEditorSessionService sessions) {
m_sessions = sessions;
}
[HttpPost]
public async Task<IActionResult> LoadDocument([FromQuery] string connectionId, [FromBody] string base64, [FromQuery] string format = "html") {
IDocumentEditorSession session = m_sessions[connectionId];
byte[] content = Convert.FromBase64String(base64);
DocumentFormat documentFormat = Enum.Parse<DocumentFormat>(format, true);
LoadOptions options = LoadOptions.FromDocumentFormat(documentFormat, content);
await session.LoadAsync(options);
return Ok(new { message = "Document loaded successfully." });
}
[HttpPost]
public async Task<IActionResult> SetParagraphColor([FromQuery] string connectionId, [FromQuery] string color = "#FFFF00") {
IDocumentEditorSession session = m_sessions[connectionId];
IParagraphFormat paragraph = session.Selection.ParagraphFormat;
await paragraph.SetBackColorAsync(color);
return Ok(new { message = $"Paragraph color set to {color}." });
}
[HttpGet]
public async Task<IActionResult> GetFieldInfo([FromQuery] string connectionId) {
IDocumentEditorSession session = m_sessions[connectionId];
IApplicationField appField = await session.ApplicationFields.GetItemAsync();
if (appField == null) return NotFound();
string name = await appField.GetNameAsync();
string typeName = await appField.GetTypeNameAsync();
string text = await appField.GetTextAsync();
return Ok(new { name, typeName, text });
}
}
Common Operations
| Operation | Description |
|---|---|
LoadAsync / SaveAsync |
Load or save documents in a session |
SetUserNamesAsync |
Manage user tracking info |
FormFields.GetElementAsync() |
Access form fields and set values |
Selection.SaveAsync() |
Retrieve selected content as HTML or RTF |
ApplicationFields.GetItemAsync() |
Retrieve merge fields at the current input position |
2.3 Namespaces Overview
| Interface | Namespace | Description |
|---|---|---|
IDocumentProcessingService |
TXTextControl.DocumentServices.DocumentProcessing.Abstractions |
Full document processing API |
IPdfApi / IAcroFormsApi / IBarcodesApi |
dto. | Sub-APIs of the processing service |
IDocumentEditorSessionService / IDocumentEditorSession |
TXTextControl.DocumentServices.DocumentEditor.Abstractions |
Access to live editor sessions |
📝 Notes
- All plugins must contain at least one public class implementing
IPlugin - Controllers must be decorated with
[ApiController]and route attributes - Middleware is registered per plugin via
ConfigureMiddleware - Services are injected using standard ASP.NET Core DI
- DS Server will invoke each lifecycle method (
ConfigureServices,ConfigureMiddleware,OnStart,OnStop) at the appropriate phase
🛡 License
This package is provided under the MIT License. See LICENSE.md for details.
📣 About Text Control DS Server
Text Control DS Server is a powerful on-premise backend for generating, viewing, editing, and signing documents — complete with extensive mail merge and reporting capabilities — accessible via REST APIs or integrated custom logic through plugins like this one. Try it out today and see how it can enhance your document processing workflows!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.