{"id":15588069,"url":"https://github.com/optimajet/dynamic-plugin-loading","last_synced_at":"2025-08-12T14:45:26.994Z","repository":{"id":225148304,"uuid":"765151652","full_name":"optimajet/dynamic-plugin-loading","owner":"optimajet","description":"Workflow Engine: Dynamic Plugin Loading","archived":false,"fork":false,"pushed_at":"2024-02-29T13:26:03.000Z","size":10,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T09:22:46.869Z","etag":null,"topics":["dynamic","plugin","tutorial","workflow-engine"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/optimajet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-02-29T11:30:14.000Z","updated_at":"2024-03-01T03:35:38.000Z","dependencies_parsed_at":"2024-02-29T14:51:31.039Z","dependency_job_id":null,"html_url":"https://github.com/optimajet/dynamic-plugin-loading","commit_stats":null,"previous_names":["optimajet/dynamic-plugin-loading"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/optimajet/dynamic-plugin-loading","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/optimajet%2Fdynamic-plugin-loading","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/optimajet%2Fdynamic-plugin-loading/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/optimajet%2Fdynamic-plugin-loading/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/optimajet%2Fdynamic-plugin-loading/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/optimajet","download_url":"https://codeload.github.com/optimajet/dynamic-plugin-loading/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/optimajet%2Fdynamic-plugin-loading/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270079975,"owners_count":24523634,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamic","plugin","tutorial","workflow-engine"],"created_at":"2024-10-02T22:21:15.803Z","updated_at":"2025-08-12T14:45:26.969Z","avatar_url":"https://github.com/optimajet.png","language":"C#","readme":"# Workflow Engine: Dynamic plugin loading\n\nIn this repository, there is a project integrated with the [WorkflowEngine](https://workflowengine.io/) \nand featuring the implementation of dynamic plugin loading. This code serves as an example of \nfollowing the tutorial outlined in the [documentation](https://workflowengine.io/documentation/dynamic-plugin-loading).\n\nIn this tutorial, we'll implement dynamic plugin loading. This allows you to customize the Workflow Engine\nby placing compiled DLLs with plugins into the *plugins* folder. Plugins are classes that implement `IWorkflowPlugin`,\nenabling the engine to incorporate new Actions, Rules, etc. Learn more about [plugins](https://workflowengine.io/documentation/plugins).\n\n### Motivation\n\nYou might be interested in this functionality for a variety of reasons:\n\n- You distribute your software with a Workflow Engine to your clients and want to provide them with customization\n  options without needing access to the source code.\n- You want to separate dependencies used in the project with the Workflow Engine from those used for plugins.\n- You manage a large number of plugins and want to simplify their modification or installation.\n\n### Environment Requirements\n\n- Application with integrated Workflow Engine.\n- IDE for working with C# code, such as [Visual Studio](https://visualstudio.microsoft.com/).\n\n## Tutorial\n\nIn this tutorial, we'll step through implementing dynamic plugin loading, which requires:\n\n1. Writing a `PluginLoader` class for dynamically loading assemblies.\n2. Adding an extension method for loading plugins into the `WorkflowRuntime`.\n3. Creating a new project with plugin implementation and exporting its DLL.\n4. Testing and ensuring everything works well.\n\n### PluginLoader\n\nThis class will inherit from the System class `AssemblyLoadContext`, aiming to correctly load DLLs and resolve\ntheir dependencies at the specified path.\n\n[Go to the code \u003ePluginLoader.cs](https://github.com/optimajet/dynamic-plugin-loading/blob/master/DynamicPluginLoading/PluginLoader.cs)\n\n### Extension Method\n\nThe extension method allows us to add dynamic loading of plugins into the Workflow Engine Runtime\ninitialization pipeline alongside other settings.\n\n[Go to the code \u003eExtensions.cs](https://github.com/optimajet/dynamic-plugin-loading/blob/master/DynamicPluginLoading/Extensions.cs)\n\n### Project with Plugin\n\nTo test the functionality, we need to create a test project from which we'll import plugins into the Workflow Engine.\nThis requires several steps:\n\n1. Create a new project `MyPlugin`.\n   ```bash\n   dotnet new classlib --name MyPlugin\n   dotnet sln add MyPlugin\n   rm MyPlugin\\Class1.cs\n   ```\n2. Add a package reference to `WorkflowEngine.NETCore-Core` to implement `IWorkflowPlugin`.\n   ```bash\n   dotnet add MyPlugin package WorkflowEngine.NETCore-Core\n   ```\n3. Add a new class `MyPlugin` implementing the `IWorkflowPlugin` interface. \n[Go to the code \u003eMyPlugin.cs](https://github.com/optimajet/dynamic-plugin-loading/blob/master/MyPlugin/MyPlugin.cs)\n4. Build the project and copy its DLL to the `plugins/{plugin_name}/…` folder.\n   ```bash\n   dotnet build\n   mkdir -p DynamicPluginLoading/bin/Debug/net8.0/plugins/MyPlugin\n   cp -r MyPlugin/bin/Debug/net8.0/* DynamicPluginLoading/bin/Debug/net8.0/plugins/MyPlugin/\n   ```\n\n### Testing\n\nFinally, we have the ability to connect dynamic plugin loading to the WorkflowRuntime creation pipeline\nwith the plugin name specified.\n\n```csharp\nvar runtime = new WorkflowRuntime()\n    .WithPlugin(new BasicPlugin())\n    // \u0026att\u003e\n    .WithDynamicPlugins(\"MyPlugin\")\n     // \u003c\u0026att\n    .AsSingleServer();\n```\n\nIf you've followed the steps exactly, `MyPlugin` will appear among the plugins in `WorkflowRuntime`,\nwhich you can verify by checking `WorkflowRuntime.Plugins`.\n\n```csharp\nforeach (var plugin in runtime.Plugins)\n{\n    Console.WriteLine($\"- {plugin.Name}\");\n}\n\n// Output:\n// - BasicPlugin\n// - MyPlugin\n```\n\n## Conclusion\n\nNow you can easily enhance plugin management in your project.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foptimajet%2Fdynamic-plugin-loading","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foptimajet%2Fdynamic-plugin-loading","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foptimajet%2Fdynamic-plugin-loading/lists"}