Load plugins based on their DisplayOrder on Startup

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 лет назад
Hi Andrei,

First let us explain how we have made our plugin infrastructure.
We have some libraries similar to the ones in nopCommerce i.e Core, Services, Framework that are referenced by all our plugins but we don't want to distribute them with each plugin.
That's why we have a Core plugin that contains all our libraries.
We have named our plugins in a way that when sorted alphabetically the Core plugin will be before the other plugins i.e:
SevenSpikes.Core
SevenSpikes.Nop.Plugins.xxx


This way we are sure the Core will be loaded first and the referenced assemblies (Core, Services, Framework) will be loaded.
Then when any other of our plugins is loaded it will find the referenced assemblies already loaded in the App Domain.

Now on startup in the PluginManager when the plugin assemblies are loaded the logic of loading the plugins is random.
To illustrate it with code:

foreach (var descriptionFile in pluginFolder.GetFiles("Description.txt", SearchOption.AllDirectories))
{ Logic of Loading a plugin assembly and all referenced assemblies here!!! }


This way there is no specific order in which the plugins are loaded.
Usually the order is based on the name of the folder in which the Description.txt file resides but this is not always the case.
Recently one of our clients had a hosting that doesn't order the folders in the Plugins folder alphabetically.
So we can't really rely on some assumptions how the operating system will sort the folders.

Could you please change the way the plugins are loaded.
Best will be to reuse the DisplayOrder in the Description.txt file.
This way we will have a predictable way in which the plugins will be loaded.

If you want we can contribute the code changes.

Many thanks.
11 лет назад
Hi Milen,

Sure. Please share your changes. Thanks a lot
11 лет назад
a.m. wrote:
Hi Milen,

Sure. Please share your changes. Thanks a lot


Hi Andrei,

Here are the code changes. We simply created a new method that does the job. No other code changes are necessary.
Simply replace the code below in PluginManager's Initialize method:

foreach (var descriptionFile in pluginFolder.GetFiles("Description.txt", SearchOption.AllDirectories))
{ Logic of Loading a plugin assembly and all referenced assemblies here!!! }


with

var descriptionFiles = GetDescriptionFilesSortedByDisplayOrder(pluginFolder);
foreach (var descriptionFile in descriptionFiles)
{ Logic of Loading a plugin assembly and all referenced assemblies here!!! }


Here is the new method GetDescriptionFilesSortedByDisplayOrder:

private static IEnumerable<FileInfo> GetDescriptionFilesSortedByDisplayOrder(DirectoryInfo pluginFolder)
        {
            // create list
            var descriptionList = new List<KeyValuePair<int, FileInfo>>();

            // add display order and path to list
            foreach (var descriptionFile in pluginFolder.GetFiles("Description.txt", SearchOption.AllDirectories))
            {
                try
                {
                    //parse file
                    var description = PluginFileParser.ParsePluginDescriptionFile(descriptionFile.FullName);

                    // populate list
                    descriptionList.Add(new KeyValuePair<int, FileInfo>(description.DisplayOrder, descriptionFile));
                }
                catch (Exception ex)
                {
                    var msg = string.Empty;
                    for (var e = ex; e != null; e = e.InnerException)
                        msg += e.Message + Environment.NewLine;

                    var fail = new Exception(msg, ex);
                    Debug.WriteLine(fail.Message, fail);

                    throw fail;
                }
            }

            // sort list by DisplayOrder. NOTE: Lowest DisplayOrder will be first i.e 0 , 1, 1, 1, 5, 10
            descriptionList.Sort((firstPair, nextPair) => firstPair.Key.CompareTo(nextPair.Key));

            var descriptionFilesSorted = new List<FileInfo>();
            descriptionList.ForEach(x => descriptionFilesSorted.Add(x.Value));
            
            return descriptionFilesSorted;
        }


We have tested it and it seems to be working fine.

Many thanks!
11 лет назад
7Spikes wrote:
Here are the code changes.
...

Thanks a lot!
11 лет назад
Done (with minor refactoring). Please see changesets d513fbaef0de and b203ef9a332e
11 лет назад
a.m. wrote:
Done (with minor refactoring). Please see changesets d513fbaef0de and b203ef9a332e


Many Thanks Andrei!
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.