Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with Elsa DropIns: Method not found: 'Elsa.Features.Services.IModule.get_Services()' #4954

Open
LukasBenner opened this issue Feb 16, 2024 · 3 comments
Labels
bug Something isn't working elsa 3 This issue is specific to Elsa 3

Comments

@LukasBenner
Copy link

So I want to use the DropIn feature.

I created a Plugin Project, that adds GRPC activities.
The activities are implemented in a project called "IOCommunicationActivies".
The GRPC functionality is implemented in a project called "GrpcClient".
The GrpcClient is referenced by the IOCommunicationActivites project.

I build the IOCommunicationActivites project and copy the output to the configured DropIns folder.
In the class DropInStartup : IDropIn in the Install method, I want to register a grpc service.
I do that by writing:

public void Install(IModule module)
{
    module.AddActivitiesFrom<DropInStartup>();
    module.Services.AddSingleton<IGrpcClient, GrpcClient.GrpcClient>(_ => new GrpcClient.GrpcClient(new Uri("")));
}

Running the Elsa Server I get the error:

Exception thrown: 'System.MissingMethodException' in Elsa.DropIns.dll
An unhandled exception of type 'System.MissingMethodException' occurred in Elsa.DropIns.dll
Method not found: 'Microsoft.Extensions.DependencyInjection.IServiceCollection Elsa.Features.Services.IModule.get_Services()'.

I'm relatively new to plugin like project configurations so I'll post the csproj files for GrpcClient and IOCommunicationActivities:
GrpcClient:

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFramework>net8.0-windows</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
		<GlobalUsings>enable</GlobalUsings>
		<EnableDynamicLoading>true</EnableDynamicLoading>
	</PropertyGroup>

	<ItemGroup>
		<Protobuf Include="protos\global.proto" GrpcServices="Client" />
		<Protobuf Include="protos\iosignalserver.proto" GrpcServices="Client" />
		<Protobuf Include="protos\cardcontroller.proto" GrpcServices="Client" />
		<Protobuf Include="protos\servercontrol.proto" GrpcServices="Client" />
	</ItemGroup>

	<ItemGroup>
		<PackageReference Include="Google.Protobuf" Version="3.25.2" />
		<PackageReference Include="Grpc.Net.Client" Version="2.60.0" />
		<PackageReference Include="Grpc.Tools" Version="2.61.0">
			<PrivateAssets>all</PrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
		</PackageReference>
	</ItemGroup>
</Project>

IOCommunicationActivities:

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFramework>net8.0-windows</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
		<EnableDynamicLoading>true</EnableDynamicLoading>
		<OutputPath>$(SolutionDir)ElsaBackend\App_Data\Plugins</OutputPath>
		<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="Elsa.DropIns.Core" Version="3.0.5">
			<ExcludeAssets>runtime</ExcludeAssets>
		</PackageReference>
		<PackageReference Include="Elsa.Workflows.Management" Version="3.0.5">
			<ExcludeAssets>runtime</ExcludeAssets>
		</PackageReference>
	</ItemGroup>

	<ItemGroup>
		<ProjectReference Include="..\GrpcClient\GrpcClient.csproj" />
	</ItemGroup>
</Project>
Copy link

glime-ai bot commented Feb 16, 2024

Based on the error message you're encountering, it seems there might be a mismatch between the versions of Elsa you're using and the method signatures expected by the DropIns feature. The error message indicates that the IModule.get_Services() method cannot be found, which suggests that the Elsa.DropIns.Core package might be expecting a different version of the Elsa core libraries than what you have installed.

Here are a few steps you can take to troubleshoot and resolve the issue:

  1. Ensure that you are using compatible versions of the Elsa packages across your projects. Since you are using Elsa.DropIns.Core version 3.0.5, make sure that all other Elsa-related packages are also on the same version.

  2. Check the release notes and documentation for the version of Elsa you are using to see if there are any breaking changes or updates to the DropIns feature that you need to be aware of.

  3. Review the csproj files for both the GrpcClient and IOCommunicationActivities projects to ensure that they are correctly configured to support dynamic loading as plugins.

  4. If you are still encountering issues, consider reaching out to the Elsa community or checking the GitHub issues for similar problems that other users may have reported. You can also look at the source code for the Elsa.DropIns.Core package to understand how it expects plugins to be registered.

  5. As a last resort, you may want to create a minimal reproducible example and submit an issue on the Elsa GitHub repository for further assistance from the maintainers.

Remember to check the compatibility of all your dependencies and ensure that you are following the latest guidelines for using the DropIns feature with Elsa 3.x.

@LukasBenner
Copy link
Author

So I was able to resolve parts of the issue. Building the IOCommunications Project copies the "Microsoft.Extensions.DependencyInjection.Abstractions.dll" DLL into the DropIns folder. Removing the file
fixes the issue and the serve doesn't crash.
However I can't explain why that file is copied to the output directory.

@LukasBenner
Copy link
Author

So the problem is, that the NuGet package "Grpc.Net.Client", that I use in my GrpcClient depends on Microsoft.Extensions.Logging.Abstractions. Microsoft.Extensions.Logging.Abstractions depends on Microsoft.Extensions.DependencyInjection.Abstractions.dll and copies it to the output directory.
Microsoft.Extensions.DependencyInjection.Abstractions.dll is also used by Elsa.DropIns.Core and having the same dll two times is a problem. Microsoft explains this in their blog as the following:

The <Private>false</Private> element is important. This tells MSBuild to not copy PluginBase.dll to the output directory for HelloPlugin. If the PluginBase.dll assembly is present in the output directory, PluginLoadContext will find the assembly there and load it when it loads the HelloPlugin.dll assembly. At this point, the HelloPlugin.HelloCommand type will implement the ICommand interface from the PluginBase.dll in the output directory of the HelloPlugin project, not the ICommand interface that is loaded into the default load context. Since the runtime sees these two types as different types from different assemblies, the AppWithPlugin.Program.CreateCommands method won't find the commands. As a result, the <Private>false</Private> metadata is required for the reference to the assembly containing the plugin interfaces.

See this thread for some additional information NuGet/Home#5986 (comment)

This problem is indeed not caused by Elsa workflow but introduces complexity for a person that wants to create plugins. Using a plugin, that depends on a dll that is already been loaded by the Elsa server, would cause a crash.

@sfmskywalker sfmskywalker added bug Something isn't working elsa 3 This issue is specific to Elsa 3 labels Feb 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working elsa 3 This issue is specific to Elsa 3
Projects
Status: No status
Development

No branches or pull requests

2 participants