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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TXTextControl.DocumentServices.Plugin.Abstractions" Version="5.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TXTextControl.DocumentServices.Plugin.Abstractions" Version="5.0.1" />
                    
Directory.Packages.props
<PackageReference Include="TXTextControl.DocumentServices.Plugin.Abstractions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TXTextControl.DocumentServices.Plugin.Abstractions --version 5.0.1
                    
#r "nuget: TXTextControl.DocumentServices.Plugin.Abstractions, 5.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TXTextControl.DocumentServices.Plugin.Abstractions@5.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TXTextControl.DocumentServices.Plugin.Abstractions&version=5.0.1
                    
Install as a Cake Addin
#tool nuget:?package=TXTextControl.DocumentServices.Plugin.Abstractions&version=5.0.1
                    
Install as a Cake Tool

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 IDocumentProcessingService or IDocumentEditorSessionService
  • 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
  1. Build your plugin:

    dotnet build
    
  2. Create a subfolder inside the Plugins/ directory of your DS Server installation (e.g. Plugins/SamplePlugin/)

  3. Copy the resulting .dll file (e.g. bin/Debug/net10.0/MyFirstPlugin.dll) into that subfolder:

    Plugins/
    └── SamplePlugin/
        └── MyFirstPlugin.dll
    
  4. Restart DS Server.

  5. 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
PDF 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • 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.

Version Downloads Last Updated
5.0.1 82 3/13/2026
5.0.0 82 3/12/2026
4.1.0 173 9/26/2025