DynamoVisualProgramming.DynamoServices by Autodesk

<PackageReference Include="DynamoVisualProgramming.DynamoServices" Version="3.0.0-beta6885" />

 PythonEngineManager

public sealed class PythonEngineManager
Singleton class that other class can access and use for query loaded Python Engine info.
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reflection; namespace Dynamo.PythonServices { public sealed class PythonEngineManager { internal static readonly Lazy<PythonEngineManager> lazy = new Lazy<PythonEngineManager>(() => new PythonEngineManager()); public ObservableCollection<PythonEngine> AvailableEngines; internal static readonly string CPython3EngineName = "CPython3"; internal static readonly string IronPython2EngineName = "IronPython2"; internal static string PythonEvaluatorSingletonInstance = "Instance"; internal static string IronPythonEvaluatorClass = "IronPythonEvaluator"; internal static string IronPythonEvaluationMethod = "EvaluateIronPythonScript"; internal static string CPythonEvaluatorClass = "CPythonEvaluator"; internal static string CPythonEvaluationMethod = "EvaluatePythonScript"; internal static string IronPythonAssemblyName = "DSIronPython"; internal static string CPythonAssemblyName = "DSCPython"; internal static string IronPythonTypeName = IronPythonAssemblyName + "." + IronPythonEvaluatorClass; internal static string CPythonTypeName = CPythonAssemblyName + "." + CPythonEvaluatorClass; internal static string PythonInputMarshalerProperty = "InputMarshaler"; internal static string PythonOutputMarshalerProperty = "OutputMarshaler"; internal static string DummyEvaluatorClass = "DummyPythonEvaluator"; internal static string DummyEvaluatorMethod = "Evaluate"; public static PythonEngineManager Instance => lazy.Value; private PythonEngineManager() { AvailableEngines = new ObservableCollection<PythonEngine>(); LoadDefaultPythonEngine(AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(delegate(Assembly a) { if (a != (Assembly)null) return a.GetName().Name == CPythonAssemblyName; return false; })); AppDomain.CurrentDomain.AssemblyLoad += delegate(object sender, AssemblyLoadEventArgs args) { LoadDefaultPythonEngine(args.LoadedAssembly); }; } private void LoadDefaultPythonEngine(Assembly a) { if (!(a == (Assembly)null) && !(a.GetName().Name != CPythonAssemblyName)) try { LoadPythonEngine(a); } catch (Exception) { } } private PythonEngine GetEngine(string version) { return AvailableEngines.FirstOrDefault((PythonEngine x) => x.Name == version); } internal void LoadPythonEngine(IEnumerable<Assembly> assemblies) { foreach (Assembly assembly in assemblies) { LoadPythonEngine(assembly); } } private void LoadPythonEngine(Assembly assembly) { if (!(assembly == (Assembly)null)) try { Type type = null; PropertyInfo propertyInfo = null; try { type = assembly.GetTypes().FirstOrDefault(delegate(Type x) { if (typeof(PythonEngine).IsAssignableFrom(x) && !x.IsInterface) return !x.IsAbstract; return false; }); if (type == (Type)null) return; propertyInfo = type?.GetProperty(PythonEvaluatorSingletonInstance, BindingFlags.Static | BindingFlags.NonPublic); if (propertyInfo == (PropertyInfo)null) return; } catch { return; } PythonEngine pythonEngine = (PythonEngine)propertyInfo.GetValue(null); if (pythonEngine == null) throw new Exception("Could not get a valid PythonEngine instance by calling the " + type.Name + "." + PythonEvaluatorSingletonInstance + " method"); if (GetEngine(pythonEngine.Name) == null) AvailableEngines.Add(pythonEngine); } catch (Exception ex) { throw new Exception("Failed to add a Python engine from assembly " + assembly.GetName().Name + ".dll with error: " + ex.Message); } } } }