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>();
LoadPythonEngine(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) {
if (args.LoadedAssembly != (Assembly)null && args.LoadedAssembly.GetName().Name == CPythonAssemblyName)
Instance.LoadPythonEngine(args.LoadedAssembly);
};
}
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 {
PythonEngine pythonEngine = (PythonEngine)(assembly.GetTypes().FirstOrDefault(delegate(Type x) {
if (typeof(PythonEngine).IsAssignableFrom(x) && !x.IsInterface)
return !x.IsAbstract;
return false;
})?.GetProperty(PythonEvaluatorSingletonInstance, BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null));
if (pythonEngine != null && GetEngine(pythonEngine.Name) == null)
AvailableEngines.Add(pythonEngine);
} catch {
}
}
}
}