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

Plugin system #79

Open
anthony-bernaert opened this issue Sep 25, 2024 · 2 comments
Open

Plugin system #79

anthony-bernaert opened this issue Sep 25, 2024 · 2 comments
Assignees
Labels
Feature Feature request

Comments

@anthony-bernaert
Copy link

I am playing around with a few ideas of which I am not sure they would 100% fit in the application. A few apps I use provide a plugin system for this type of extensions. I think it can also be a good way to keep the core application 'tidy' by not having to implement feature requests from a minority of users. From my experience, .NET actually makes it relatively easy to implement such a plugin architecture.

Do you think it would be possible to make this? The amount of customization could be kept simple to start with. The use cases I was thinking of:

  • Custom import sources (e.g. discovering files from a shared OneDrive directory link)
  • Custom meta data or maybe even preview extractors (e.g. Word/other Office documents)

That would allow other developers (e.g. me) to add specific functionality. Plugins would be made open-source afterwards, of course.

@DSPaul
Copy link
Owner

DSPaul commented Sep 25, 2024

I've definitely also thought about it and agree it would be a great addition. Especially because the barcode reader alone is responsible for over half of the install size so splitting that of into a separate plugin would be great. It would also allow the rpg integrations to become optional as some people just want to use it for general purpose files.

The reasons I haven't done it yet are the following:

  • I have very little experience with plugin systems (only a small uni project adding a plugin system in a Java application) so would need to do some learning to properly implement it.
  • You only really get one shot at it, because once plugins are made, you cannot change the system without breaking all of them. So I don't want to rush it, and take my time to do it right, no temporary "this will do for now".
  • I would need a kind of plugin repo that is preferably browsable in app which adds additional complexity, hosting, server infra, curration, ect. Because I don't want people to have to download random dll's from the internet to install them. It's both super user unfriendly and a security hazard.
  • It seems like a lot of work and there are more important changes that I would like to get done first, such as the port to Avalonia.

Could you link some sources on how dotnet supports such an architecture as you mentioned?

@anthony-bernaert
Copy link
Author

The only experience with plugins I had until now is nopCommerce. As far as I know, nopCommerce doesn't use any packages for plugins, and implements all plugin loading logic itself. I think their DI-based approach is really powerful and nice to develop for, but it's certainly not perfect. There is tight coupling between the core version and plugin version, and external plugins I've used therefore often provide a build per nopCommerce version. This works because you typically don't update your eCommerce framework as often as you would update a desktop app.

In general, I see lots of references to MEF when I look up on how to write a plugin architecture, yet it seems a bit outdated (see here). Instead, there are alternatives such as DotNetCorePlugins, described on this blog post, and this seems rather neat. It's a lightweight package that handles assembly and dependency loading.

As I found the plugin subject interesting, I did a few experiences within the COMPASS code (however, before reading about DotNetCorePlugins). You can find it on the plugin_poc branch of my fork. For assembly loading, it still uses the more naive Assembly.LoadFrom approach, but it works for now if you build everything as a whole (note my changes did break your Tests though). For integrating new WPF views in the 2 sample plugins, I've been inspired by this article and associated Github repo.

While making this, a few challenges appeared:

  • How to share (Codex/Collection/...) model information between core/plugin?
  • How to expose services to the plugin?
  • How to have common XAML for reusing theme/interface elements?
  • How to deal with version differences between plugin and core?

Referring back to the nopCommerce example: they make a distinction between core and framework features, and put them in separate C# projects/class libraries, ensuring proper decoupling. I don't know if you'll need a lot of architectural changes for moving to Avalonia, but it is maybe also a refactoring opportunity - even if you don't implement plugins in the end.

Lastly, for version differences, I found this post about using an adapter pattern.

Note I really don't want to push you in any direction - I understand that there are higher priorities. The subject draw my interest and I made the demo mainly for own learning purposes (both on plugins, but also more basic MVVM/WPF). I'm sharing it so you can possibly refer to it in the future and see how things can be done (or shouldn't be done 😄).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Feature request
Projects
Status: Planned Long Term
Development

No branches or pull requests

2 participants