Example #1
0
        internal static void LoadAndInitializePlugins(TalknetEnv env)
        {
            var pluginsCache = new List <LoadedPlugin>();

            pluginsCache.AddRange(LoadSelf());
            pluginsCache.AddRange(LoadFromPluginDirectory());

            // unique
            foreach (var plugin in pluginsCache)
            {
                var name = plugin.Info.Name;

                if (Plugins.ContainsKey(name))
                {
                    if (plugin.PluginInstance.GetType().IsInstanceOfType(Plugins[name].PluginInstance))
                    {
                        continue;
                    }
                    throw new PluginLoadingException(string.Format(ErrMsg.PluginSameName, name, Plugins[name], plugin));
                }

                Plugins[name] = plugin;
            }

            // check requirements
            var refs = new DAG <string>(Plugins.Keys);

            foreach (var plugin in pluginsCache)
            {
                var thisName = plugin.Info.Name;

                foreach (var req in plugin.Requirements)
                {
                    var reqName = req.Requirement;

                    if (!Plugins.ContainsKey(reqName))
                    {
                        throw PluginLoadingException.ErrorReqNotSatisfied(plugin, reqName);
                    }

                    switch (req.Order)
                    {
                    case LoadOrderType.ThisFirst:
                        refs.AddEdge(thisName, reqName);
                        break;

                    case LoadOrderType.RequiredFirst:
                        refs.AddEdge(reqName, thisName);
                        break;

                    default:
                        continue;
                    }
                }
            }

            _order = null;
            try {
                _order = refs.TopologicalOrder();
            } catch (NotADagException) {
                throw new PluginLoadingException(ErrMsg.LoadOrderCannotBeSatisfied);
            }

            foreach (var it in _order)
            {
                Plugins[it].PluginInstance.PluginInitialize(env);
            }
        }
Example #2
0
        // do not handle exceptions, just throw them
        internal static IEnumerable <LoadedPlugin> LoadFromAssembly(Assembly ass, string from)
        {
            var cache = new List <LoadedPlugin>();

            TalknetPluginAssemblyAttribute attrAssembly;

            if ((attrAssembly = ass.GetCustomAttribute(typeof(TalknetPluginAssemblyAttribute)) as TalknetPluginAssemblyAttribute) == null)
            {
                return(new LoadedPlugin[0]);
            }

            var pluginsProvided = attrAssembly.Plugins;

            if (pluginsProvided == null || pluginsProvided.Length == 0)
            {
                throw new PluginLoadingException(Clet.AssemblyNoPluginList, from);
            }

            foreach (var pluginType in pluginsProvided)
            {
                if (pluginType == null)
                {
                    throw new PluginLoadingException(Clet.PluginListNullItem, from);
                }

                if (!pluginType.GetInterfaces().Contains(typeof(ITalknetPlugin)))
                {
                    throw new PluginLoadingException(Clet.PluginNoInterface, from, pluginType.FullName);
                }
                TalknetPluginAttribute attr = null;

                try {
                    if (pluginType.GetCustomAttribute(typeof(TalknetPluginAttribute)) is TalknetPluginAttribute v)
                    {
                        attr = v;
                    }
                } catch (Exception ex) {
                    throw PluginLoadingException.ErrorGettingAttr(from, pluginType.FullName, ex);
                }

                if (attr == null)
                {
                    throw new PluginLoadingException(Clet.PluginNoAttribute, from, pluginType.FullName);
                }

                // so it is
                var info         = attr.Info;
                var ins          = Activator.CreateInstance(pluginType) as ITalknetPlugin;
                var requirements = pluginType.GetCustomAttributes(typeof(RequireAttribute)).Select(t => t as RequireAttribute);

                if (!_pluginNameRegex.IsMatch(info.Name))
                {
                    throw new PluginLoadingException(Clet.PluginInvalidName, from, pluginType.FullName);
                }

                cache.Add(new LoadedPlugin {
                    Info = info, PluginInstance = ins, Source = from, Requirements = requirements.ToArray()
                });
            }

            return(cache);
        }