From c7152db4c5b8d29436fe66ba39d23de54d605cb9 Mon Sep 17 00:00:00 2001 From: Robert Cornea Date: Thu, 14 May 2026 10:37:58 +0300 Subject: [PATCH] LG-53877 LG-53879 - review core section --- apiconcepts/core/extensions.md | 87 +++++++++---------- apiconcepts/core/overview.md | 54 ++++++------ apiconcepts/core/pluginOverview.md | 9 -- .../plugin_resources_and_localizability.md | 26 +++--- apiconcepts/core/serialization_performance.md | 19 ++-- .../core/the_plugin_manifest_generator.md | 13 ++- apiconcepts/overview.md | 16 ++-- apiconcepts/toc.yml | 17 ++-- writing_guidelines.md | 2 +- 9 files changed, 118 insertions(+), 125 deletions(-) delete mode 100644 apiconcepts/core/pluginOverview.md diff --git a/apiconcepts/core/extensions.md b/apiconcepts/core/extensions.md index b012cd7dab..214586d3ab 100644 --- a/apiconcepts/core/extensions.md +++ b/apiconcepts/core/extensions.md @@ -1,78 +1,77 @@ -Extensions and extension points -==== -Var:ProductName offers a predefined set of extension points. Your plug-ins can add custom functionality to Var:ProductName by defining extensions that target these extension points. +# Extensions and Extension Points +Var:ProductName provides a predefined set of extension points. You can add custom functionality by defining plug-in extensions that target those points. -### Extensions -An extension is an individual unit of logic that provides functionality for Var:ProductName through a specific extension point. -You can create an extension by following the steps below: +### Extensions +An extension is a unit of logic that provides functionality for Var:ProductName through a specific extension point. +To create an extension: 1. Create a class in your plug-in assembly. 2. Decorate the class with the attribute that identifies the extension point it is targeting. 3. Implement the interface that is required by the extension point. -### Extension points -An extension point is a point in Var:ProductName that allows adding extensions to it. -You can define an extension point by following the steps below: +### Extension Points +An extension point is a location in Var:ProductName where extensions can be added. +To define an extension point: 1. Create a class in your plug-in assembly and derive it from the [ExtensionAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionAttribute.yml) base. 2. Decorate the class with the [ExtensionPointInfoAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionPointInfoAttribute.yml) attribute. -3. Make sure that the class has a default parameterless constructor. This is needed because the [plugin manifest generator](the_plugin_manifest_generator.md) uses XML serialization to save attribute information. +3. Make sure the class has a default parameterless constructor. This is required because the [plugin manifest generator](the_plugin_manifest_generator.md) uses XML serialization to save attribute information. -Other plug-in developers can create extensions for the extension points you define, by following the procedure described under [Extensions](#extensions). +Other plug-in developers can create extensions for the extension points you define by following the procedure described under [Extensions](#extensions). The [ExtensionAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionAttribute.yml) class defines the properties that plug-in developers can provide with their extensions: -* *Id*: A unique id for the extension -* *Name*: A friendly name for the extension. -* *Description*: A description of the extension. -* *Icon*: An optional icon representing the extension. +* **Id**: A unique identifier for the extension. +* **Name**: A friendly name for the extension. +* **Description**: A description of the extension. +* **Icon**: An optional icon representing the extension. -The [ExtensionPointInfoAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionPointInfoAttribute.yml) class specifies the name and type of the extension point: -* The name can be used by a plug-in manager UI to represent the extension point. -* The type can be either static or dynamic, referring to whether this extension point allows enabling or disabling of one or more of its extensions without having to restart the application. +The [ExtensionPointInfoAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionPointInfoAttribute.yml) class specifies the name and type of the extension point: +* **Name**: Can be used by a plug-in manager UI to represent the extension point. +* **Type**: Can be static or dynamic, depending on whether one or more extensions can be enabled or disabled without restarting the application. -#### Example: Defining an extension point -We will demonstrate the various topics presented in this article using a message transmitter example. Our requirement is that the host application is able to use pluggable message transmitters that are defined in plug-ins. +#### Example: Defining an Extension Point +This article uses a message transmitter example to demonstrate the concepts. The host application must be able to use pluggable message transmitters defined in plug-ins. -First, we need to define an extension point: +First, define an extension point: # [C#](#tab/tabid-1) [!code-csharp[MessageTransmitterAttribute](code_samples/MessageTransmitterAttribute.cs#L9-L45)] ***
-The purpose of the message transmitter attribute is to allow plug-in developers to use it to annotate their message transmitter extension classes, to make them known as message transmitter implementations to the extension point. +The message transmitter attribute allows plug-in developers to annotate message transmitter extension classes so they are recognized by the extension point as valid message transmitter implementations. -Note that we have defined an extra property, CostPerCharacter, which indicates the cost in dollars for each character sent in a message. +This example defines an extra property, `CostPerCharacter`, which indicates the cost in dollars for each character sent in a message. -Since all these properties will be extracted to the plug-in manifest file by the plug-in manifest generator, the host application will be able to access their values without having to create an instance of the actual transmitters or even load the plug-in assembly. Since the plug-in manifest generator uses XML serialization to save the attribute information, the attribute has have a default, parameterless constructor. +All these properties are extracted to the plug-in manifest file by the plug-in manifest generator. As a result, the host application can access the values without creating an instance of the actual transmitters or loading the plug-in assembly. Because the plug-in manifest generator uses XML serialization to save attribute information, the attribute must have a default, parameterless constructor. -We still have to define which functionality is required from an extension class to be accepted as a valid message transmitter by the host application. This is done by defining an interface: +Next, define which functionality an extension class must provide to be accepted as a valid message transmitter by the host application. This is done by defining an interface: # [C#](#tab/tabid-1) [!code-csharp[IMessageTransmitter](code_samples/IMessageTransmitter.cs#L7-L10)] ***
-This simple interface contains one method, SendMessage, to be called by the host application to send the message. +This simple interface contains one method, `SendMessage`, which is called by the host application to send a message. -#### Example: Creating extensions for an extension point -Let's define a message transmitter which transmits messages by email, the `EmailMessageTransmitter` class: +#### Example: Creating Extensions for an Extension Point +Define a message transmitter that sends messages by email: the `EmailMessageTransmitter` class. # [C#](#tab/tabid-1) [!code-csharp[EmailMessageTransmitter](code_samples/EmailMessageTransmitter.cs#L7-L20)] ***
-The `EmailMessageTransmitter` class implements the `IMessageTransmitter` interface. On top of that, the class is annotated with the extension attribute, `MessageTransmitter`, which we defined earlier, providing an id, a name, a description and the cost per character when sending messages using this transmitter. +The `EmailMessageTransmitter` class implements the `IMessageTransmitter` interface. In addition, the class is annotated with the `MessageTransmitter` extension attribute, which was defined earlier and provides an ID, name, description, and cost per character. -Similar to the email transmitter, we also define an SMS message transmitter in exactly the same way. We can do this within the same plug-in project, because a plug-in project can contain multiple extensions. +Similar to the email transmitter, an SMS message transmitter can be defined in the same way. This can be done in the same plug-in project, because a plug-in project can contain multiple extensions. # [C#](#tab/tabid-1) [!code-csharp[SMSMessageTransmitter](code_samples/SMSMessageTransmitter.cs#L7-L29)] *** ### Auxiliary Extension Attributes -In some cases, you might need to add some extra metadata to a certain extension implementation, on top of what is defined in the extension attribute and it might be impractical to add these properties to the extension attribute itself. +In some cases, you might need to add extra metadata to an extension implementation beyond what is defined in the extension attribute, and it might be impractical to add those properties to the extension attribute itself. -An example of this is for instance a plug-in user action. The extension attribute for the action can define name, icon, tooltip etc, but you also need to specify on which menus, toolbars and context menus this user action will be available. For cases like this, the plug-in framework provides auxiliary extension attributes. +For example, consider a plug-in user action. The extension attribute for the action can define a name, icon, and tooltip, but you also need to specify which menus, toolbars, and context menus make the action available. For these cases, the plug-in framework provides auxiliary extension attributes. You can only apply one extension attribute to an extension implementation: this is the attribute that uniquely identifies the extension point the extension implementation is targeting. On top of this, you can decorate the implementation class with as many auxiliary extension attributes as you like. @@ -99,22 +98,22 @@ In order to solve this common use case, the plug-in framework provides the [Sort You can use the [SortedObjectRegistry](../../api/core/Sdl.Core.PluginFramework.Util.SortedObjectRegistry-2.yml) class to create instances of all extensions for a sortable extension point and sort these according to the values of the `InsertBefore` and `InsertAfter` properties. -In case you want more control when ordering extensions, you can use the [TopologicalSort< T>](../../api/core/Sdl.Core.PluginFramework.Util.TopologicalSort-1.yml) class, which implements the sorting algorithm. You then need to provide wrapper objects that implement [ITopologicalSortable](../../api/core/Sdl.Core.PluginFramework.Util.ITopologicalSortable.yml) for each extension. +If you need more control when ordering extensions, you can use the [TopologicalSort< T>](../../api/core/Sdl.Core.PluginFramework.Util.TopologicalSort-1.yml) class, which implements the sorting algorithm. You then need to provide wrapper objects that implement [ITopologicalSortable](../../api/core/Sdl.Core.PluginFramework.Util.ITopologicalSortable.yml) for each extension. -### Compile-time extension validation -In order to catch as many developer errors as possible at compile-time, the plug-in framework provides a mechanism for extension point developers to validate extension definitions at compile-time. +### Compile-time Extension Validation +To catch as many developer errors as possible at compile time, the plug-in framework provides a mechanism for extension point developers to validate extension definitions during build. Every [ExtensionAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionAttribute.yml) and [AuxiliaryExtensionAttribute](../../api/core/Sdl.Core.PluginFramework.AuxiliaryExtensionAttribute.yml) has validation methods which are called during the build process. These methods then have the ability to report errors and warnings, which will be displayed in Visual Studio as standard compiler errors. **Extension Attribute Validation** -The [ExtensionAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionAttribute.yml) type has a `Validate` method, which by default validates that the user has specified values for the `Id` and the `Name` property. When developing and extension point, this method can be overridden to perform additional validation. +When developing an extension point, this method can be overridden to perform additional validation. **Auxiliary Extension Attribute Validation** The [AuxiliaryExtensionAttribute](../../api/core/Sdl.Core.PluginFramework.AuxiliaryExtensionAttribute.yml) type also has a `Validate` method, which by default doesn't do any special validation. Extension point developers can override this method to perform additional validation for an auxiliary extension attribute. -#### Example: Compile-time extension validation +#### Example: Compile-time Extension Validation In our message transmitter example, the extension point checks whether the extension implements the IMessageTransmitter interface. If an extension does not implement this interface, an error will be generated at compile time. # [C#](#tab/tabid-1) @@ -122,7 +121,7 @@ In our message transmitter example, the extension point checks whether the exten *** ### Consuming extensions using the PluginRegistry and ObjectRegistry -The [IPluginRegistry](../../api/core/Sdl.Core.PluginFramework.IPluginRegistry.yml) object is the main object that can be used by the host application or component in order to access and instantiate the available plug-ins. +The [IPluginRegistry](../../api/core/Sdl.Core.PluginFramework.IPluginRegistry.yml) object is the main object used by a host application or component to access and instantiate available plug-ins. The [PluginManager](../../api/core/Sdl.Core.PluginFramework.PluginManager.yml) static class, which is the entry point to the plug-in framework object model, provides various ways to create instances of the [IPluginRegistry](../../api/core/Sdl.Core.PluginFramework.IPluginRegistry.yml) object. By default, plug-ins are installed in the applications installation directory and plug-in manifest and resource files are installed in a "plugins" subdirectory. In order to access these plugins, you can use the `DefaultPluginRegistry` property, which returns an [IPluginRegistry](../../api/core/Sdl.Core.PluginFramework.IPluginRegistry.yml) instance, that has been configured to load plug-ins from that default location. @@ -134,11 +133,11 @@ The `CreateObjects` method simply instantiates all the extension implementations For sortable extension points, you can use the corresponding [SortedObjectRegistry](../../api/core/Sdl.Core.PluginFramework.Util.SortedObjectRegistry-2.yml) class. -#### Example: Using the PluginRegistry -Returning to our message transmitter example, we want to write some custom code that sends a message using a message transmitter. Also, we will let the user select the transmitter they would like to use. +#### Example: Using the PluginRegistry +Returning to the message transmitter example, the next step is to write custom code that sends a message by using a message transmitter. The user can select which transmitter to use. -Message transmitters are defined in plugins. In order to use them we need to do several things. -First, we get the extension point from the plug-in registry. An extension point is represented by the [IExtensionPoint](../../api/core/Sdl.Core.PluginFramework.IExtensionPoint.yml) interface and provides access to all extensions discovered for that extension point. We identify our desired extension point by passing `MessageTransmitterAttribute` as the template parameter: +Message transmitters are defined in plug-ins. To use them, several steps are required. +First, get the extension point from the plug-in registry. An extension point is represented by the [IExtensionPoint](../../api/core/Sdl.Core.PluginFramework.IExtensionPoint.yml) interface and provides access to all extensions discovered for that extension point. The desired extension point is identified by passing `MessageTransmitterAttribute` as the template parameter: # [C#](#tab/tabid-1) [!code-csharp[HostApplication](code_samples/HostApplication.cs#L17-L18)] @@ -152,14 +151,14 @@ Second, prompt the user to enter a message: ***
-Next, list all the available message transmitters, along with their name and the cost per character. This is done by iterating over the Extensions collection of the extension point, which contains [IExtension](../../api/core/Sdl.Core.PluginFramework.IExtension.yml) objects. These provide access to the extension attribute that was used to annotate the respective extension implementation classes. The name and cost per character can be retreived from that `MessageTransmitterAttribute`: +Next, list all available message transmitters, along with their name and cost per character. This is done by iterating over the Extensions collection of the extension point, which contains [IExtension](../../api/core/Sdl.Core.PluginFramework.IExtension.yml) objects. These provide access to the extension attribute used to annotate the corresponding extension implementation classes. The name and cost per character can be retrieved from `MessageTransmitterAttribute`: # [C#](#tab/tabid-1) [!code-csharp[HostApplication](code_samples/HostApplication.cs#L31-L45)] ***
-Now get the extension object corresponding to the user's choice, and also get hold of the extension attribute instance: +Now get the extension object corresponding to the user's choice, and retrieve the extension attribute instance: # [C#](#tab/tabid-1) [!code-csharp[HostApplication](code_samples/HostApplication.cs#L51-L51)] diff --git a/apiconcepts/core/overview.md b/apiconcepts/core/overview.md index 0f5d76b543..5a9487bab0 100644 --- a/apiconcepts/core/overview.md +++ b/apiconcepts/core/overview.md @@ -1,26 +1,28 @@ -Plug-in Framework Overview -==== -This help system describes the Plug-in Framework. This framework offers plug-in functionality to applications and components. Application developers can define extension points and dynamically load any plug-ins providing extensions targeting these extension points using the plug-in framework. - -Version ---- -The version of the Plug-in Framework documented here is the one that was released with Var:ProductNameWithEdition. - -Main Concepts and Definitions ----- -This section introduces a number of concepts and definitions that are central to the plug-in framework. - -* **Hosting Application**
- This is the application (or component) which provides plug-in capabilities. The hosting application will define certain extension points and will use the plug-in framework to discover and load plug-ins and extensions for these extension points.

-* **Extension Point**
- An extension point is a point in the application or component that allows adding extensions to it. An extension point is defined by a .Net attribute, called an extension attribute. All extension attributes should derive from the [ExtensionAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionAttribute.yml) base class.

-* **Extension**
- An extension is an individual unit of logic that adds functionality to an application or component through a specific extension point. An extension is defined by a .Net class, defined in a plug-in assembly, annotated with the extension attribute that identifies the extension point it targets. An extension class typically implements an interface that is required by the extension point it is targeting.

-* **Plug-in**
- A plug-in can contain one or more extensions. A plug-in consist is a .Net assembly which is annotated with the assembly-level [PluginAttribute](../../api/core/Sdl.Core.PluginFramework.PluginAttribute.yml), which has a Name property that contains the friendly name of the plug-in. The presence of this attribute tells the framework that this is a plug-in assembly.

-* **Plug-in Registry**
- The central object in the plug-in framework is the plug-in registry ([IPluginRegistry](../../api/core/Sdl.Core.PluginFramework.IPluginRegistry.yml)). The plug-in registry provides functionality to the host application to detect which plug-ins and extensions are available and create instances of the extensions provided by these plug-ins.

-* **Plug-in Manifest**
- A plug-in manifest is an XML file, which contains serialized metadata about a plug-in assembly, it contains: - * The plug-in name, plus the plug-in assembly's name and version. - * A list of all the extensions defined within the plug-in assembly, together with the meta data defined in the extension attributes. +# Plug-in Framework Overview +The Plug-in Framework enables applications and components to support plug-in functionality. Developers can define extension points and dynamically load plug-ins that provide targeted extensions using this framework. + +## Version +This documentation covers the version of the Plug-in Framework released with `Var:ProductNameWithEdition`. + +## Main Concepts and Definitions +This section outlines key concepts and definitions central to the Plug-in Framework. + +### Hosting Application +The hosting application (or component) provides plug-in capabilities. It defines extension points and uses the Plug-in Framework to discover and load plug-ins and extensions for these points. + +### Extension Point +An extension point is a location in the application or component that supports adding extensions. It is defined by a .NET attribute, called an extension attribute. All extension attributes derive from the [ExtensionAttribute](../../api/core/Sdl.Core.PluginFramework.ExtensionAttribute.yml) base class. + +### Extension +An extension is a unit of logic that enhances an application or component through a specific extension point. It is defined by a .NET class within a plug-in assembly and annotated with the extension attribute identifying its target extension point. Typically, an extension class implements an interface required by the targeted extension point. + +### Plug-in +A plug-in contains one or more extensions. It is a .NET assembly annotated with the assembly-level [PluginAttribute](../../api/core/Sdl.Core.PluginFramework.PluginAttribute.yml), which includes a Name property for the plug-in's friendly name. This attribute indicates to the framework that the assembly is a plug-in. + +### Plug-in Registry +The plug-in registry ([IPluginRegistry](../../api/core/Sdl.Core.PluginFramework.IPluginRegistry.yml)) is the central object in the framework. It enables the host application to detect available plug-ins and extensions and create instances of the extensions provided by these plug-ins. + +### Plug-in Manifest +A plug-in manifest is an XML file containing serialized metadata about a plug-in assembly. It includes: +- The plug-in name, assembly name, and version. +- A list of all extensions defined within the plug-in assembly, along with metadata specified in the extension attributes. diff --git a/apiconcepts/core/pluginOverview.md b/apiconcepts/core/pluginOverview.md deleted file mode 100644 index d40f7e07ef..0000000000 --- a/apiconcepts/core/pluginOverview.md +++ /dev/null @@ -1,9 +0,0 @@ -Plugin overview -===== -This section gives a detailed description of the mechanisms behind building a plugin. - -The following topics will be covered: - -* [Plug-in Resource and Localization](plugin_resources_and_localizability.md): How to localize plug-in extension points -* [The Plug-in Manifest Generator](the_plugin_manifest_generator.md): Information about how plug-ins manifests are created. -* [Serialization Performance](serialization_performance.md): Information on how to ensure good plug-in loading performance. diff --git a/apiconcepts/core/plugin_resources_and_localizability.md b/apiconcepts/core/plugin_resources_and_localizability.md index 45fa9caefa..24e04741b5 100644 --- a/apiconcepts/core/plugin_resources_and_localizability.md +++ b/apiconcepts/core/plugin_resources_and_localizability.md @@ -1,41 +1,43 @@ -Plug-in Resources and Localizability -====== +# Plug-in Resources and Localizability This section explains how to make extension meta-data localizable. -Plug-in Resources and Localizability ------ -All the string metadata values used for the properties of the extension attributes shown in the example above are hard-coded strings. In reality these strings need to be localized. +## Overview +All string metadata values used for the properties of extension attributes in the example above are hard-coded strings. These strings need to be localized. -For that reason, the framework allows adding a specific plug-in resource file to a plug-in project. Instead of hard-coding the strings in code, you can specify the key of a resource string defined in the plug-in resources file. The framework resolves these resource strings at runtime based on the current UI culture and automatically populates the string properties of extension attributes with the corresponding localized values. +To achieve this, the framework allows adding a specific plug-in resource file to a plug-in project. Instead of hard-coding strings in code, you can specify the key of a resource string defined in the plug-in resource file. The framework resolves these resource strings at runtime based on the current UI culture and automatically populates the string properties of extension attributes with the corresponding localized values. -To indicate that the value of a certain property needs to be retrieved from the plug-in resources file, the definition of that property within the extension attribute definition must be annotated with the `PluginResource` attribute. For instance, a plug-in button extension point, with a localizable `ToolTipText` property becomes: +### Using the `PluginResource` Attribute +To indicate that a property's value needs to be retrieved from the plug-in resource file, annotate the property within the extension attribute definition with the `PluginResource` attribute. For example, a plug-in button extension point with a localizable `ToolTipText` property becomes: # [C#](#tab/tabid-1) [!code-csharp[AdvancedPluginFramework](code_samples/AdvancedPluginFramework.cs#L25-L34)] ***
-An extension targeting this extension point, `MyPluginButton`: +An extension targeting this extension point, `MyPluginButton`, is defined as: # [C#](#tab/tabid-2) [!code-csharp[AdvancedPluginFramework](code_samples/AdvancedPluginFramework.cs#L40-L50)] ***
-In the above code sample, `MyPluginButton_Name` and `MyPluginButton_ToolTipText` are keys of strings defined in the plugin resource file, `PluginResources.resx`. -As mentioned before, the plug-in manifest generator requires that you pass the path to the plug-in resx file as the second parameter. To avoid having to load the plug-in assembly to get access to the embedded resource strings when the plug-in meta data is accessed, the plug-in manifest generator compiles an external .Net plug-in resource file. This compiled resource file is copied alongside the plug-in manifest file, so that it can be loaded separately from the plug-in assembly itself. For instance, for the plug-in assembly, PluginLibrary, this becomes: +In the above code sample, `MyPluginButton_Name` and `MyPluginButton_ToolTipText` are keys of strings defined in the plug-in resource file, `PluginResources.resx`. +The plug-in manifest generator requires the path to the plug-in `.resx` file as the second parameter. To avoid loading the plug-in assembly to access embedded resource strings when accessing plug-in metadata, the manifest generator compiles an external .NET plug-in resource file. This compiled resource file is copied alongside the plug-in manifest file, allowing it to be loaded separately from the plug-in assembly. For example, for the plug-in assembly `PluginLibrary`, the following files are generated: * `PluginLibrary.dll`: the plug-in assembly * `PluginLibrary.plugin.xml`: the plug-in manifest file * `PluginLibrary.plugin.resources`: the plug-in resources file containing strings for the neutral culture. * `PluginLibrary.plugin.*.resources`: any number of resource files containing the localized strings -The use of the `PluginResource` attribute is supported in the following cases: +### Supported Use Cases +The `PluginResource` attribute can be used in the following cases: * Extension attribute string properties * Auxiliary extension attribute string properties * Assembly-level `PluginAttribute` string attributes -For non-string properties, like for instance an icon, the plug-in resource file can also be used, however, because of the type difference, the value of these kinds of properties cannot be automatically resolved. Define the actual property as a string property, to which uses must assign a resource key. Then, when you need the actual icon, get it from the plug-in resource file using the `GetPluginResource` method: + +### Non-String Properties +For non-string properties, such as an icon, the plug-in resource file can also be used. However, due to type differences, these properties cannot be automatically resolved. Define the property as a string property, and assign a resource key to it. When the actual icon is needed, retrieve it from the plug-in resource file using the `GetPluginResource` method: # [C#](#tab/tabid-3) [!code-csharp[AdvancedPluginFramework](code_samples/AdvancedPluginFramework.cs#L16-L17)] diff --git a/apiconcepts/core/serialization_performance.md b/apiconcepts/core/serialization_performance.md index 43e042dae5..ff84638179 100644 --- a/apiconcepts/core/serialization_performance.md +++ b/apiconcepts/core/serialization_performance.md @@ -1,19 +1,22 @@ -Serialization Performance -===== +## Serialization Performance This section describes how to make sure that extensions can be loaded in the most optimal way. -Serialization Performance ------ +### Overview The automatic serialization mechanism that comes with .Net is quite handy, since it let’s you serialize and deserialize objects to and from xml in a virtually a single line of code. -However, as it is often the case, there is a downside to this ease of use: the first time you serialize an object of a certain type, the .Net runtime uses reflection to get the list of properties of the type, then automatically generates code that can serialize and deserialize these properties, compiles that code to an assembly, and finally loads it. +However, this ease of use comes with a downside: the first time you serialize an object of a certain type, the .NET runtime uses reflection to retrieve the list of properties of the type. It then generates code to serialize and deserialize these properties, compiles the code into an assembly, and loads it. -Especially in the desktop application scenario, this will impact performance dramatically, since this process will be repeated for every extension or auxiliary extension attribute type that is used at start-up. +In desktop application scenarios, this process can significantly impact performance, as it is repeated for every extension or auxiliary extension attribute type used at startup. -We can avoid this automatic serialization overhead, by explicitly implementing the `System.Xml.Serialization.IXmlSerializable` interface. The extension attribute base class already defines the methods required by this interface: `GetSchema`, `ReadXml` and `WriteXml`. All you need to do is mark your attribute class to implement `IXmlSerializable` and override `ReadXml` and `WriteXml` to read and write additional properties, making sure to call the base class method to read and write the base class properties: +### Optimizing Serialization +To avoid the overhead of automatic serialization, explicitly implement the `System.Xml.Serialization.IXmlSerializable` interface. The extension attribute base class already defines the methods required by this interface: `GetSchema`, `ReadXml`, and `WriteXml`. To optimize serialization: + +1. Mark your attribute class to implement `IXmlSerializable`. +2. Override `ReadXml` and `WriteXml` to handle additional properties. +3. Ensure you call the base class methods to read and write base class properties. # [C#](#tab/tabid-1) [!code-csharp[AdvancedPluginFramework](code_samples/AdvancedPluginFramework.cs#L85-L110)] *** -The plug-in framework calls the `ReadXml` and `WriteXml` methods directly, avoiding the overhead of automatic xml serialization. \ No newline at end of file +The plug-in framework directly calls the `ReadXml` and `WriteXml` methods, eliminating the overhead of automatic XML serialization. diff --git a/apiconcepts/core/the_plugin_manifest_generator.md b/apiconcepts/core/the_plugin_manifest_generator.md index fa61c451a7..2c93900f59 100644 --- a/apiconcepts/core/the_plugin_manifest_generator.md +++ b/apiconcepts/core/the_plugin_manifest_generator.md @@ -1,15 +1,14 @@ --- uid: the_plugin_manifest_generator.md --- -The Plug-in Manifest Generator -====== -The section describes how plug-in projects are built and how the plug-in manifest is generated. +## The Plug-in Manifest Generator +This section describes how plug-in projects are built and how the plug-in manifest is generated. -Plug-in Manifest Generator ----- -The purpose of the plug-in manifest is to avoid loading all the plug-in assemblies at runtime and reflecting over them to discover the available extensions, which would affect startup performance, an important aspect of desktop applications. +### Overview +The plug-in manifest prevents the need to load all plug-in assemblies at runtime and reflect over them to discover available extensions. This optimization significantly improves startup performance, which is critical for desktop applications. - The plug-in manifest generator is implemented as an MSBuild task, which runs as part of the standard Var:VisualStudioEdition build. This build task is contained in [Sdl.Core.PluginFramework.Build](https://www.nuget.org/packages/Sdl.Core.PluginFramework.Build/) package that needs to be refreneced by the project. +### Implementation +The plug-in manifest generator is implemented as an MSBuild task, running as part of the standard Var:VisualStudioEdition build. This build task is included in the [Sdl.Core.PluginFramework.Build](https://www.nuget.org/packages/Sdl.Core.PluginFramework.Build/) package, which must be referenced by the project. ```xml diff --git a/apiconcepts/overview.md b/apiconcepts/overview.md index e50b08b183..76990081d5 100644 --- a/apiconcepts/overview.md +++ b/apiconcepts/overview.md @@ -1,23 +1,23 @@ ## [Core](core/overview.md) -This is the foundation which provides the plug-in framework available in Var:ProductName, used by other APIs to define extension points inside the software. +The Core API is the foundation of Var:ProductName, providing the plug-in framework that enables other APIs to define extension points within the software. ## [File Type Support Framework](filetypesupport/overview.md) -In order to translate content from a certain file type, Var:ProductName extracts it into an SDLXliff. If you want to work with an unsupported file type that isn't already available with Var:ProductName, you can use this API to extract the content and create the SDLXliff needed for translation. +The File Type Support Framework API enables you to work with unsupported file types by extracting their content and generating the SDLXliff required for translation in Var:ProductName. ## [Project Automation](projectautomation/overview.md) -There are many activities that must be done as part of the translation process and this is why Var:ProductName provides project management features, such as analysis, pre-translation and more. Using the Project Automation API, you can build a customized translation workflow based on activities specific to your needs. +The Project Automation API allows you to streamline translation workflows by automating project management activities such as analysis, pre-translation, and more. ## [Translation Memory](translationmemory/overview.md) -Translation memories are an essential piece of technology for translators. Var:ProductName comes with this capability, but if you're interested in using a different piece of technology for translation memories, you can enable that in Var:ProductName by creating a new translation memory provider. +The Translation Memory API lets you integrate alternative translation memory technologies into Var:ProductName by developing custom translation memory providers. ## [Integration](integration/overview.md) -This API enables you to extend or customize the user interface or create custom functionalities for Var:ProductName. You can create new views, new sections in the menu ribbon, new options in the context menu or hook into the editor to create, update or delete certain information. +The Integration API enables you to enhance or customize the user interface and functionalities of Var:ProductName, including creating new views, adding menu options, and hooking into the editor. ## [Verification](verification/overview.md) -Var:ProductName allows translators to check their work by running verifiers during translation. There are many ways to verify the quality of a translation and it can also become very specific. So to address that need, Var:ProductName allows custom verifiers to be built and run. +The Verification API allows you to create and run custom verifiers to ensure translation quality during the translation process in Var:ProductName. ## [Batch Tasks](batchtasks/overview.md) -As part of a project management workflow, there are certain tasks that need to be applied, such as pre-translation, analysis and more. Var:ProductName comes with a predefined set of tasks, but with this API, you can also create your own custom tasks that can be included in your workflows. +The Batch Tasks API lets you develop custom tasks for project workflows, extending the predefined tasks available in Var:ProductName. ## [Terminology Provider](terminology/overview.md) -This API allows you to enable the use of different terminology technology in Var:ProductName, by creating new terminology providers. +The Terminology Provider API enables you to integrate alternative terminology technologies into Var:ProductName by building custom terminology providers. diff --git a/apiconcepts/toc.yml b/apiconcepts/toc.yml index 266b431208..8ac9c8afcb 100644 --- a/apiconcepts/toc.yml +++ b/apiconcepts/toc.yml @@ -4,16 +4,13 @@ href: core/overview.md items: - name: Plug-in Framework Overview - href: core/overview.md - - name: Plugin overview - href: core/pluginOverview.md - items: - - name: Plug-in Resources and Localizability - href: core/plugin_resources_and_localizability.md - - name: The Plug-in Manifest Generator - href: core/the_plugin_manifest_generator.md - - name: Serialization Performance - href: core/serialization_performance.md + href: core/overview.md + - name: Plug-in Resources and Localizability + href: core/plugin_resources_and_localizability.md + - name: The Plug-in Manifest Generator + href: core/the_plugin_manifest_generator.md + - name: Serialization Performance + href: core/serialization_performance.md - name: Extensions and extension points href: core/extensions.md - name: API Reference diff --git a/writing_guidelines.md b/writing_guidelines.md index cf92c6e08e..64d1331a88 100644 --- a/writing_guidelines.md +++ b/writing_guidelines.md @@ -12,7 +12,7 @@ Here's a short example for active voice: > The cat sat on the mat. * actor: The cat -* verd: sat +* verb: sat * target: the mat Here's a short example for passive voice: