4

私たちのプロジェクトには、顧客がVisualBasicでスクリプト化できる簡単なビジネスルールを持つ能力が必要です。私たちのメインプログラムはC#で書かれていますが

顧客が実行したいスクリプトは次のようになります(私は可能な限り単純なケースを検討しています)

var vbCode = @"
    If (Row.Code = 12) Then 
        Row.MappedCode = 1
    End If";

そこで、CodeプロパティとMappedCodeプロパティを使用してC#でRowDataクラスを作成しました

namespace ScriptModel
{
    public class RowData
    {
        public int Code { get; set; }
        public int MappedCode { get; set; }
    }
}

次のような単純なホストオブジェクトクラスを作成しました

namespace ScriptModel
{
    public class HostObjectModel
    {
        public RowData Row { get; set; }

    }
}

Roslyn.Scripting.VisualBasic.ScriptEngineを使用してエンジンを作成し、HostObjectModelのインスタンスを使用してセッションを作成し、engine.Execute(vbCode、session)を実行します。

   var hostObj = new HostObjectModel();

   hostObj.Row = new RowData();
   hostObj.Row.Code = 12;

   var engine = new Roslyn.Scripting.VisualBasic.ScriptEngine(
                    new Assembly[] {hostObj.GetType().Assembly},
                    new string[] {"ScriptModel"} );

   var session = Session.Create(hostObj);

   engine.Execute(vbCode , session); 

そしてそれは私にそれを教えてくれます

(2,25):エラーBC30451:「行」が宣言されていません。保護レベルが原因でアクセスできない場合があります。

しかし、C#で同様のコードスニペットを作成すると

 var csharpCode = @"
                    if (Row.Code == 12) 
                    {  
                        Row.MappedCode = 1;
                    };";

CSharp.ScriptEngineを使用すると、すべて正しく機能します

では、何が問題なのか、なぜVisualBasic.ScriptEngineがC#でコンパイルされたクラスのパブリックプロパティを表示できないのか、同じMSIL言語に基づいているのか、それとも間違っているのでしょうか。


更新:Visual Basicをインストールし、VBにScriptModelライブラリを作成しました。また、クラス宣言とvbCodeの両方でRowプロパティをRow()関数に置き換えました。どちらも役に立たなかった。:( C#から実行すると、VisualBasic.ScriptEngineがまったく機能しないようです。

4

2 に答える 2

3

VBスクリプトの場合、スクリプトの先頭に次のものを含める必要があることがわかりました。

Imports ScriptModel

上記をコード文字列の前に自動的に追加して、ユーザーがそれを含めることを覚えておく必要がないようにすることができると思います。

ScriptEngineの作成の一部として追加したときに、それを機能させることができませんでした。また、以下を使用しても、後で機能しないようです。

engine.ImportedNamespaces.Append("ScriptModel");

これは、後でImportedNamespacesの数が1であるという事実にもかかわらずです。c#を使用すると、名前空間をインポートする必要がまったくないようです。

于 2012-06-30T03:28:20.647 に答える
1

VB.NETスクリプトを機能させる方法が本当にわかったので、前の回答を受け入れましたが、HostObjectはまだ機能しません。

したがって、実際の回避策は2つのステップで構成されます

1)VBコードでImportsScriptModelを使用する

var vbCode = @"Imports ScriptModel

    If (Row.Code = 12) Then 
        Row.MappedCode = 1
    End If";

2)HostObjectを使用しないでください。行をパブリック静的クラスとして定義する

namespace ScriptModel
{
    public static class Row
    {
        public static int Code { get; set; }
        public static int MappedCode { get; set; }
    }
}

MSフォーラムの回答も正しいと思います。http://social.msdn.microsoft.com/Forums/en-US/roslyn/thread/89970f0b-1c1c-47da-a180-9c4710abc4b9現在のバージョンではHostObjectはサポートされていませんVBですが、次のバージョンでサポートされることを願っています

于 2012-07-04T13:52:45.540 に答える