|
| 1 | +--- |
| 2 | +title: Build and package plug-in code |
| 3 | +description: Learn about building plug-in code into assemblies and packages for later registration and upload to the Microsoft Dataverse service. |
| 4 | +ms.date: 10/02/2023 |
| 5 | +ms.reviewer: pehecke |
| 6 | +ms.topic: article |
| 7 | +author: divkamath |
| 8 | +ms.subservice: dataverse-developer |
| 9 | +ms.author: dikamath |
| 10 | +search.audienceType: |
| 11 | + - developer |
| 12 | +contributors: |
| 13 | + - phecke |
| 14 | + - JimDaly |
| 15 | +--- |
| 16 | + |
| 17 | +# Build and package plug-in code |
| 18 | + |
| 19 | +This article describes what you need to know about configuring and building an assembly for your plug-in project. We'll also discuss how to create a plug-in package that can contain your plug-in assembly plus any other require dependent assemblies your plug-in needs at run-time. |
| 20 | + |
| 21 | +## Building the plug-in assembly |
| 22 | + |
| 23 | +When building a plug-in project, keep the following output assembly constraints in mind. |
| 24 | + |
| 25 | +### Use .NET Framework 4.6.2 |
| 26 | + |
| 27 | +Plug-in and custom workflow activity assembly projects must target .NET Framework 4.6.2. While assemblies built using later versions of the .NET Framework should generally work, if the plug-in code uses any features introduced after 4.6.2, a run-time error will occur. |
| 28 | + |
| 29 | +### Optimize assembly development |
| 30 | + |
| 31 | +Your assembly may include multiple plug-in classes (or types) and even custom workflow activities, but can be no larger than 16 MB in size. It's recommended to consolidate plug-ins and workflow assemblies into a single assembly as long as the size remains below 16 MB. |
| 32 | + |
| 33 | +Best practice information: [Optimize assembly development](/dynamics365/customer-engagement/guidance/server/optimize-assembly-development) |
| 34 | + |
| 35 | +### Signed assemblies are required |
| 36 | + |
| 37 | +Assemblies must be signed before they can be registered with Dataverse only if you are not using the [dependent assemblies](#dependent-assemblies) capability. You can use the Visual Studio **Signing** tab in your project's properties or the [Sn.exe (Strong Name Tool)](/dotnet/framework/tools/sn-exe-strong-name-tool) command to sign the assembly. |
| 38 | + |
| 39 | +### Dependency on the CoreAssemblies NuGet package |
| 40 | + |
| 41 | +Adding the `Microsoft.CrmSdk.CoreAssemblies` NuGet package to your project includes the required Dataverse assembly references in your project, but it doesn't upload these assemblies along with your plug-in assembly as these assemblies already exist in the server's sandbox run-time where your code will execute. |
| 42 | + |
| 43 | +### Where to go next |
| 44 | + |
| 45 | +If you are interested in learning about or using dependent assemblies, continue reading the next section in this article. If not, proceed to [Register a plug-in](register-plug-in.md). |
| 46 | + |
| 47 | +## Dependent assemblies |
| 48 | + |
| 49 | +The dependent assembly capability can be used to include other required .NET assemblies or resources (for example, localized strings) with your plug-in assembly in a single [NuGet](https://www.nuget.org) package that is uploaded to the Dataverse server during the registration process. |
| 50 | + |
| 51 | +> [!IMPORTANT] |
| 52 | +> The dependent assembly capability is so important to plug-in development that you should consider using it from the start even if you do not have an immediate need to do so. Adding support for dependent assemblies to your plug-in project is much more difficult later on in the development cycle. |
| 53 | +> |
| 54 | +> We do not supported use of ILMerge. This dependent assemblies feature provides a solution we can support with the same functionality as ILMerge and more. |
| 55 | +
|
| 56 | +This NuGet package file is stored in the [PluginPackage](reference/entities/pluginpackage.md) table. The contents of the NuGet package is stored in file storage rather than the SQL database. |
| 57 | + |
| 58 | +When you upload your NuGet package, any assemblies containing classes that implement the <xref:Microsoft.Xrm.Sdk.IPlugin> interface are registered in the [PluginAssembly](reference/entities/pluginassembly.md) table and associated with the plug-in package. As you develop and maintain your project, you continue to update the `PluginPackage` table row and changes to the related plug-in assemblies are managed on the server. |
| 59 | + |
| 60 | +At runtime, Dataverse copies the contents of the NuGet package from the `PluginPackage` row and extracts it to the sandbox runtime. This way, any dependent assemblies needed for the plug-in are available. |
| 61 | + |
| 62 | +### Signed assemblies are not required |
| 63 | + |
| 64 | +You aren't required to sign plug-in assemblies used in plug-in packages. |
| 65 | + |
| 66 | +When you register individual plug-in assemblies without the dependent assemblies capability, signing is required because it provides a unique name for the assembly. But with plug-in assemblies within a plug-in package, the assemblies are loaded on the sandbox server using a different mechanism, so signing isn't necessary. |
| 67 | + |
| 68 | +> [!IMPORTANT] |
| 69 | +> If you sign your assemblies, be aware that signed assemblies cannot use resources contained in unsigned assemblies. If you sign your plug-in assemblies or any dependent assembly, all the assemblies that those assemblies depend on must be signed. |
| 70 | +> |
| 71 | +> If any signed assemblies depend on unsigned assemblies, you will get an error similar to the following: Could not load file or assembly \<AssemblyName>, Version=\<Version>, Culture=neutral, PublicKeyToken=null or one of its dependencies. A strongly-named assembly is required. |
| 72 | +
|
| 73 | +### Dependent assemblies limitations |
| 74 | + |
| 75 | +The following limitations apply when using plug-in dependent assemblies. |
| 76 | + |
| 77 | +- [Workflow extensions](workflow/workflow-extensions.md), also known as *custom workflow activities* aren't supported when using the dependent assemblies capability. |
| 78 | +- Plug-ins for virtual table data providers aren't supported. |
| 79 | +- On-premises environments aren't supported. |
| 80 | +- Un-managed code isn't supported. You can't include references to unmanaged resources. |
| 81 | + |
| 82 | +## Creating a plug-in package |
| 83 | + |
| 84 | +Your plug-in assembly plus any required dependent assemblies can be placed together in a NuGet package and then registered and uploaded to the Dataverse server. You do not need to create a package if your plug-in project does not require any dependent assemblies at run-time, other than what ships in the Microsoft.CrmSdk.CoreAssemblies NuGet package. |
| 85 | + |
| 86 | +<!-- Add correct links when available --> |
| 87 | +Instructions for creating a plug-in package using an interactive tool can be found in these separate how-to's: [Create and register a plug-in package using PAC CLI](/power-platform/developer/howto/cli-create-package), [Create and register a plug-in package using Visual Studio](/power-platform/developer/howto/vs-create-package). |
| 88 | + |
| 89 | +### Don't depend on System.Text.Json |
| 90 | + |
| 91 | +Because the Microsoft.CrmSdk.CoreAssemblies NuGet package has a [dependency](https://www.nuget.org/packages/Microsoft.CrmSdk.CoreAssemblies#dependencies-body-tab) on System.Text.Json, you're able to refer to [System.Text.Json](xref:System.Text.Json) types at design time. However, the System.Text.Json.dll file in the sandbox run-time can't be guaranteed to be the same version that you reference in your project. If you need to use `System.Text.Json`, you should use the dependent assembly feature and explicitly include it in your NuGet package. |
| 92 | + |
| 93 | +### See also |
| 94 | + |
| 95 | +[Use plug-ins to extend business processes](plug-ins.md) |
| 96 | + |
| 97 | +[!INCLUDE[footer-include](../../includes/footer-banner.md)] |
0 commit comments