Прямо сейчас я работаю над проектом, и команда хочет найти способ писать код и редактировать его без необходимости перекомпилировать весь проект, поэтому я решил попробовать реализовать скриптовый движок.
Реализовав ранее Lua в C++, я не был новичком в реализации возможностей сценариев в проектах. Однако мы хотели попробовать реализовать прямой C#, используя пространство имен Microsoft.CSharp в сочетании с System.Reflection, которая уже была встроена в C#.
Услышав об этом, я порылся в документации и нашел прототип, который ПОЧТИ работает, но не совсем.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
namespace Scripting
{
class Program
{
static void Main(string[] args)
{
StringBuilder builder = new StringBuilder();
builder.Append("using System;");
builder.Append("using Scripting;");
builder.Append("class MyScript : IScript");
builder.Append("{");
builder.Append(" string ScriptName");
builder.Append(" {");
builder.Append(" get { return \"My Script\"; }");
builder.Append(" }");
builder.Append(" public bool Initialize()");
builder.Append(" {");
builder.Append(" Console.WriteLine(\"Hello, World!\");");
builder.Append(" return true;");
builder.Append(" }");
builder.Append("}");
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters param = new CompilerParameters(new string[] { "System.dll", "Scripting.dll" });
param.GenerateInMemory = true;
param.GenerateExecutable = true;
CompilerResults result = provider.CompileAssemblyFromSource(param, builder.ToString());
if (result.Errors.Count > 0)
{
foreach (CompilerError error in result.Errors)
Console.WriteLine(error);
Console.ReadKey();
return;
}
}
}
}
Проблема, с которой я столкнулся на данный момент, заключается в том, что я хочу иметь возможность ссылаться на свой интерфейс — IScript.cs (который находится внутри пространства имен Scripting и, следовательно, текущей сборки) — чтобы скрипты, написанные и проанализированные в компиляторе, могли получить к нему доступ. Очевидно, я добавил Scripting.dll в качестве параметра, но по той или иной причине к нему, похоже, нет доступа. Я запускаюего в режиме отладки, так что это может быть причиной некоторых серьезных фейспалмагий. Что?
Есть ли способ сослаться на текущую сборку и передать ее в CompilerParameters? Или я чертовски облажался / должен ли я полагаться на создание сборки для объектов сценария / и т.д?