// private List<ScriptableMethodInfo> _methods;
        // public ReadOnlyCollection<ScriptableMethodInfo> Methods { get; private set; }

        private ServerMethodScriptGenerator(ServerMethodPluginRegistration registration, string assemblyInstanceId, PluginInfo pluginInfo) : base(assemblyInstanceId, pluginInfo)
        {
            this.Registration = registration;
        }
        public static ServerMethodScriptGenerator Create(ServerMethodPluginRegistration registration, PluginInfo pluginInfo)
        {
            var ret = new ServerMethodScriptGenerator(registration, registration.PluginAssemblyInstanceId, pluginInfo);

            ret.Process();
            return(ret);
        }
Example #3
0
        //AssemblyLoadContext, AssemblyName, Assembly?
        // private Assembly OnResolveAssembly(AssemblyLoadContext ctx, AssemblyName asmName)
        // {
        //     try
        //     {
        //         // try and find relative to existing assebmlies loaded in ctx
        //         foreach (var asm in ctx.Assemblies)
        //         {
        //             var fi = new FileInfo(asm.Location);

        //             var path = Path.Combine(fi.DirectoryName, asmName.Name + ".dll");

        //             if (File.Exists(path))
        //             {
        //                 try
        //                 {
        //                     var loadedAsm = ctx.LoadFromAssemblyPath(path);
        //                     if (loadedAsm != null) return loadedAsm;
        //                 }
        //                 catch { }
        //             }
        //         }

        //         SessionLog.Error($"Failed to resolve {asmName.FullName} in context {ctx.Name}");
        //         return null;
        //     }
        //     catch
        //     {
        //         return null;
        //     }
        // }

        // private Assembly OnResolveAssembly(object sender, ResolveEventArgs e)
        // {
        //     try
        //     {
        //         var asmName = new AssemblyName(e.Name);
        //         var requestingLocation = e.RequestingAssembly.Location;
        //         var requestingDir = Path.GetDirectoryName(requestingLocation);

        //         // look for a dll in the same location as the requesting assembly
        //         var path = Path.Combine(requestingDir, asmName.Name + ".dll");

        //         if (!File.Exists(path)) return null;

        //         Assembly.LoadFrom(path);

        //         return null;
        //     }
        //     catch
        //     {
        //         return null;
        //     }
        // }

        // private void InitServerWidePlugins()
        // {
        //     try
        //     {
        //         if (PluginAssemblies == null) return;

        //         foreach (var pluginAssembly in PluginAssemblies)
        //         {
        //             var pluginInfoCollection = pluginAssembly.Plugins.Where(p => p.Type == OM.PluginType.ServerMethod || p.Type == OM.PluginType.BackgroundThread);

        //             foreach (var pluginInfo in pluginInfoCollection)
        //             {
        //                 if (pluginInfo.Type == OM.PluginType.BackgroundThread)
        //                 {
        //                     _backgroundThreadManager.Register(pluginInfo);
        //                 }
        //                 else if (pluginInfo.Type == OM.PluginType.ServerMethod)
        //                 {
        //                     ServerMethodManager.Register(pluginAssembly.InstanceId, pluginInfo);
        //                 }
        //             }
        //         }
        //     }
        //     catch (Exception ex)
        //     {
        //         SessionLog.Exception(ex);
        //     }
        // }


        // parses an Assembly and checks for Plugin-type interface. If found each of those interfaces are tested for validity in terms of mandatory Attribute values and uniqueness
        private bool ParsePluginAssembly(Assembly pluginAssembly, out List <PluginInfo> pluginInfoList, out List <string> errorList, bool checkForConflict = true)
        {
            errorList      = new List <string>();
            pluginInfoList = new List <PluginInfo>();

            if (pluginAssembly.DefinedTypes != null)
            {
                var pluginTypeList = pluginAssembly.DefinedTypes.Where(typ => typ.IsSubclassOf(typeof(PluginBase))).ToList();

                if (pluginTypeList != null && pluginTypeList.Count > 0)
                {
                    foreach (var pluginType in pluginTypeList)
                    {
                        var pluginInfo = new PluginInfo();

                        try
                        {
                            var pluginData = pluginType.GetCustomAttribute(typeof(PluginDataAttribute)) as PluginDataAttribute;

                            if (pluginData == null)
                            {
                                errorList.Add($"Plugin '{pluginType.FullName}' from assembly '{pluginAssembly.FullName}' does not have a PluginData attribute defined on the class level. Add a jsdal_plugin.PluginDataAttribute to the class.");
                                continue;
                            }

                            if (!Guid.TryParse(pluginData.Guid, out var pluginGuid))
                            {
                                errorList.Add($"Plugin '{pluginType.FullName}' does not have a valid Guid value set on its PluginData attribute.");
                                continue;
                            }

                            if (checkForConflict)
                            {
                                var conflict = PluginAssemblies.SelectMany(a => a.Plugins).FirstOrDefault(p => p.Guid.Equals(pluginGuid));

                                if (conflict != null)
                                {
                                    errorList.Add($"Plugin '{pluginType.FullName}' has a conflicting Guid. The conflict is on assembly {conflict.TypeInfo.FullName} and plugin '{conflict.Name}' with Guid value {conflict.Guid}.");
                                    continue;
                                }
                            }

                            if (pluginType.IsSubclassOf(typeof(ExecutionPlugin)))
                            {
                                pluginInfo.Type = OM.PluginType.Execution;
                            }
                            else if (pluginType.IsSubclassOf(typeof(BackgroundThreadPlugin)))
                            {
                                pluginInfo.Type = OM.PluginType.BackgroundThread;
                            }
                            else if (pluginType.IsSubclassOf(typeof(ServerMethodPlugin)))
                            {
                                pluginInfo.Type = OM.PluginType.ServerMethod;


                                // TODO: Additional validation: Look for at least on ServerMethod? otherwise just a warning?
                                //      What about unique names of ServerMethods?
                                //      Validate Custom Namespace validity (must be JavaScript safe)
                            }
                            else
                            {
                                errorList.Add($"Unknown plugin type '{pluginType.FullName}'.");
                                continue;
                            }

                            pluginInfo.Assembly    = pluginAssembly;
                            pluginInfo.Name        = pluginData.Name;
                            pluginInfo.Description = pluginData.Description;
                            pluginInfo.TypeInfo    = pluginType;
                            pluginInfo.Guid        = pluginGuid;

                            //errorList.Add($"Plugin '{pluginInfo.Name}' ({pluginInfo.Guid}) loaded. Assembly: {pluginAssembly.FullName}");
                            pluginInfoList.Add(pluginInfo);
                        }
                        catch (Exception ex)
                        {
                            errorList.Add("Failed to instantiate type '{pluginType.FullName}'.");
                            errorList.Add(ex.ToString());

                            SessionLog.Error("Failed to instantiate type '{0}'. See the exception that follows.", pluginType.FullName);
                            SessionLog.Exception(ex);
                        }
                    }
                }
                else
                {
                    errorList.Add($"Failed to find any jsDAL Server plugins in the assembly '{pluginAssembly.Location}'. Make sure you have a public class available that derives from one of the plugin types.");
                }
            }
            else
            {
                errorList.Add($"Failed to find any jsDAL Server plugins in the assembly '{pluginAssembly.Location}'. Make sure you have a public class available that derives from one of the plugin types.");
            }

            return(errorList == null || errorList.Count == 0);
        }