// 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); }
//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); }