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

Implement Plugin Dependency Validation to Avoid Missing Plugins #40

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

Ts-Pytham
Copy link

This PR enhances the plugin loading system by ensuring that plugins with dependencies are loaded correctly. If a plugin requires another plugin to function, the system will now validate its existence before proceeding. If a required dependency is missing, a PluginNotFoundException is thrown to prevent partial or broken plugin execution.

Why This Feature?

Previously, the system assumed that all plugins listed in the configuration were valid and did not check for missing dependencies. This could lead to runtime failures or unexpected behavior when a plugin tried to reference another plugin that wasn't loaded. By adding explicit dependency resolution, we:

Prevent runtime errors due to missing dependencies.
Improve plugin management by making dependency requirements clear.
Allow safer dynamic loading of plugins.
Ensure that plugin loading is idempotent and efficient.

Key Changes:

✅ Added dependency validation before loading a plugin.
✅ Throws PluginNotFoundException if a required dependency is missing.
✅ Updated the LoadPluginsWithDependencies method to check dependencies before loading.
✅ Improved XML documentation to clarify method behavior and expectations.
✅ Added unit tests to verify correct plugin dependency resolution.

Impact & Compatibility:

This change does not break existing functionality but enhances it by ensuring plugins are loaded in the correct order.
If a plugin is missing a required dependency, an exception is now thrown instead of failing silently.
Existing users will need to ensure that all dependencies are correctly listed in their configuration files.

Se ha añadido un nuevo método abstracto `GetPluginConfigFiles` en la clase `CPluginConfigurationBase` que devuelve una colección de objetos `PluginConfig`. Este método nunca devuelve `null` y proporciona información detallada sobre la ubicación de los archivos de plugins.

En las clases `CPluginEnvConfiguration` y `CPluginJsonConfiguration`, se ha implementado el método `GetPluginConfigFiles` lanzando una excepción `NotImplementedException`, indicando que aún no se ha proporcionado una implementación concreta.

Se ha añadido una nueva clase `PluginConfig` en el archivo `PluginConfig.cs` que contiene dos propiedades: `Name` (nombre del plugin) y `DependsOn` (lista de dependencias del plugin).

Se han eliminado algunas declaraciones `using` innecesarias en el archivo `CPluginJsonConfiguration.cs`.
Se ha modificado la clase `CPluginJsonConfiguration` para implementar el método `GetPluginConfigFiles`, que ahora devuelve una lista de objetos `PluginConfig` obtenidos de la configuración JSON. Anteriormente, este método lanzaba una excepción `NotImplementedException`.

Se ha añadido una nueva prueba en la clase `CPluginJsonConfigurationTests` llamada `GetPluginConfigFiles_WhenPluginFilesArePresent_ShouldReturnsFullPaths`. Esta prueba verifica que el método `GetPluginConfigFiles` devuelve las rutas completas de los plugins cuando están presentes en la configuración JSON.

Se ha añadido un archivo JSON `settingsWithDependencies.json` que contiene la configuración de los plugins con sus dependencias, utilizado en la nueva prueba para verificar el comportamiento del método `GetPluginConfigFiles`.
Se ha ampliado la documentación en el archivo `CPluginJsonConfiguration.cs`
para incluir un ejemplo detallado sobre cómo manejar dependencias entre
plugins en la configuración JSON. Este ejemplo muestra cómo estructurar
el JSON para definir plugins que dependen de otros plugins, proporcionando
una guía clara para los desarrolladores sobre cómo configurar estas
dependencias correctamente.
Se ha añadido documentación adicional en `CPluginEnvConfiguration.cs` y `CPluginJsonConfiguration.cs` para explicar cómo manejar plugins con dependencias en la variable de entorno `PLUGINS` y en la configuración JSON, respectivamente.

Se ha eliminado el método `GetPluginConfigFiles` que lanzaba una excepción `NotImplementedException` y se ha implementado una nueva versión que obtiene la variable de entorno `PLUGINS`, la divide en archivos de plugins y sus dependencias, y devuelve una lista de objetos `PluginConfig`.

Se ha añadido una nueva prueba en `CPluginEnvConfigurationTests.cs` para verificar que el método `GetPluginConfigFiles` obtiene correctamente los archivos de plugins y sus dependencias desde un archivo de entorno.

Se ha añadido un archivo de entorno de prueba `testwithdependencies.env` que define la variable `PLUGINS` con dos plugins, uno de los cuales depende del otro.
Se han eliminado las importaciones innecesarias de `System`, `System.Collections.Generic` y `System.Linq`.

Se ha modificado la declaración del espacio de nombres a `namespace CPlugin.Net;`.

Se han ajustado los comentarios de ejemplo para mejorar la claridad en la representación de las dependencias de los plugins.
Se ha añadido un nuevo espacio de nombres `CPlugin.Net.Exceptions` en `PluginLoader.cs`.
Se ha añadido el método `LoadPluginsWithDependencies` en `PluginLoader` para cargar plugins con sus dependencias y lanzar `PluginNotFoundException` si alguna dependencia no se encuentra.
Se ha creado la clase `PluginNotFoundException` en `PluginNotFoundException.cs`.
Se han añadido dos tests en `PluginLoaderTests.cs` para verificar la carga de plugins y el lanzamiento de excepciones.
Se ha añadido el uso del espacio de nombres `CPlugin.Net.Exceptions` en `PluginLoaderTests.cs`.
Se han añadido dos nuevos métodos de prueba a la clase `PluginLoaderTests` en el archivo `PluginLoaderTests.cs`:

1. `LoadPluginsWithDependencies_WhenPluginsAreIndependent_ShouldBeLoadedIntoMemory`:
   - Verifica la carga correcta de plugins independientes en memoria.
   - Configura la variable de entorno "PLUGINS".
   - Crea una instancia de `CPluginEnvConfiguration`.
   - Espera la carga de 2 ensamblados.
   - Llama a `PluginLoader.LoadPluginsWithDependencies`.
   - Verifica que los ensamblados cargados coincidan con los esperados.

2. `LoadPluginsWithDependencies_WhenPluginsHaveMultipleDependencies_ShouldBeLoaded`:
   - Verifica la carga correcta de plugins con múltiples dependencias.
   - Define una lista de plugins y sus dependencias.
   - Configura la variable de entorno "PLUGINS".
   - Crea una instancia de `CPluginEnvConfiguration`.
   - Espera la carga de 3 ensamblados.
   - Llama a `PluginLoader.LoadPluginsWithDependencies`.
   - Verifica que los ensamblados cargados coincidan con los esperados.
Se ha añadido el método `LoadPluginsWithDependencies` a la clase `PluginLoader` en `PluginLoader.cs`. Este método carga plugins y sus dependencias desde una fuente de configuración especificada, asegurando que todas las dependencias se resuelvan antes de cargar un plugin. El método es idempotente y lanza excepciones `PluginNotFoundException` y `ArgumentNullException` en caso de errores.

En `PluginLoaderTests.cs`, se ha añadido una aserción para verificar que los ensamblados esperados se han cargado tras llamar a `LoadPluginsWithDependencies`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant