Jak hostować silnik IronPythona w oddzielnej aplikacji AppDomain?
Próbowałem tego, co oczywiste:
var appDomain = AppDomain.CreateDomain("New Domain");
var engine = IronPython.Hosting.Python.CreateEngine(appDomain); // boom!
Ale otrzymuję następujący komunikat o błędzie:Typ nie został rozwiązany dla elementu 'Microsoft.Scripting.Hosting.ScriptRuntimeSetup, Microsoft.Scripting, Version = 0.9.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35'.
Googling dla tego błędu nie okazał się owocny!
EDYCJA # 1:
Próbowałem stworzyć minimalny projekt odtwarzający, kopiując odpowiednie elementy do nowej aplikacji konsoli:
using System;
using Microsoft.Scripting;
namespace PythonHostSamle
{
class Program
{
static void Main(string[] args)
{
AppDomain sandbox = AppDomain.CreateDomain("sandbox");
var engine = IronPython.Hosting.Python.CreateEngine(sandbox);
var searchPaths = engine.GetSearchPaths();
searchPaths.Add(@"C:\Python25\Lib");
searchPaths.Add(@"C:\RevitPythonShell");
engine.SetSearchPaths(searchPaths);
var scope = engine.CreateScope();
//scope.SetVariable("revit", _application);
//engine.Runtime.IO.SetOutput(new ScriptOutputStream(_instance), Encoding.UTF8);
//engine.Runtime.IO.SetErrorOutput(new ScriptOutputStream(_instance), Encoding.UTF8);
var script = engine.CreateScriptSourceFromString("print 'hello, world!'", SourceCodeKind.Statements);
script.Execute(scope);
Console.ReadKey();
}
}
}
To działa zgodnie z oczekiwaniami!
Pozostaje mi zatem dojść do wniosku, że błąd, który otrzymuję, jest związany zjedna z linii, którą skomentowałem: Zakres dodany do silnika zawiera obiekt, nad którym mam niewielką kontrolę - odniesienie do hosta wtyczki, w którym to oprogramowanie ma działać (Autodesk Revit Architecture 2010).
Może próbując przekazać to, co tworzy błąd?
Czy istnieje sposób przekazania serwera proxy? (będzie musiał wyszukiwać usługi .NET zdalnie ...)
EDYCJA # 2:
Problem został zredukowany do przekazania obiektu za pomocą zakresu, który nie może być przypisany do innej domeny AppDomain: wszystkie obiekty dodane do zakresu interpretera IronPythona działającego w innej domenie aplikacji będą musiały być jakoś rozłożoneMarshalByRefObject
lub bądźSerializable
.