私はアプリケーションに特定のモジュラ機能を追加しようとしています。ユーザーが独自のクラスを作成し、実行時にそれらをプログラムにインポートする必要があります。私は新しいクラスの中で関数を呼び出すことができます。実行時にクラスをコンパイルしてアクセスする
例えば、クラスがあり得る:http://pastebin.com/90NTjia9
Iクラスをコンパイルした後のdoSomething()を実行することになります。
どのようにC#でこれを達成できますか?
私はアプリケーションに特定のモジュラ機能を追加しようとしています。ユーザーが独自のクラスを作成し、実行時にそれらをプログラムにインポートする必要があります。私は新しいクラスの中で関数を呼び出すことができます。実行時にクラスをコンパイルしてアクセスする
例えば、クラスがあり得る:http://pastebin.com/90NTjia9
Iクラスをコンパイルした後のdoSomething()を実行することになります。
どのようにC#でこれを達成できますか?
ユーザーが(彼らはC#クラスを書いている場合、彼らは本当に持つべきなのVisual Studioなど、)必要なツールを持っている場合、彼らはあなたがして、動的にロードすることができ、DLLを提供することができます:
は、private static T CreateInstance(string assemblyName, string typeName)
{
var assembly = Assembly.LoadFrom(assemblyName);
if (assembly == null)
throw new InvalidOperationException(
"The specified assembly '" + assemblyName + "' did not load.");
Type type = assembly.GetType(typeName);
if (type == null)
throw new InvalidOperationException(
"The specified type '" + typeName + "' was not found in assembly '" + assemblyName + "'");
return (T)Activator.CreateInstance(type);
}
あなたがタイプのインスタンスをキャストするabstract
class
またはinterface
を渡すことができるように、Tジェネリックパラメータがあります:
public interface IDoSomething
{
bool DoSomething();
}
ユーザーがINH彼らは自分のクラスを記述し、このインターフェイスからerit:
public class UserDefinedClass : IDoSomething
{
public bool DoSomething()
{
// Implementation here.
}
}
これは、型の安全性を保持し、むしろそうするためにリフレクションに頼るよりも、直接クラスメソッドを呼び出すことができます。
あなたが本当にあなたのユーザーがC#のソースを提供したい場合は、compile their class at runtimeこのようにすることができます。そして、
private Assembly BuildAssembly(string code)
{
var provider = new CSharpCodeProvider();
var compiler = provider.CreateCompiler();
var compilerparams = new CompilerParameters();
compilerparams.GenerateExecutable = false;
compilerparams.GenerateInMemory = true;
var results = compiler.CompileAssemblyFromSource(compilerparams, code);
if (results.Errors.HasErrors)
{
var errors = new StringBuilder("Compiler Errors :\r\n");
foreach (CompilerError error in results.Errors)
{
errors.AppendFormat("Line {0},{1}\t: {2}\n",
error.Line, error.Column, error.ErrorText);
}
throw new Exception(errors.ToString());
}
else
{
return results.CompiledAssembly;
}
}
、あなただけの代わりに、外部から読み込まれたアセンブリの、上記CreateInstance
コードに結果のアセンブリを置き換えてください。ユーザーは、クラスの先頭に適切なusing
ステートメントを提供する必要があります。
実際に完全なクラスを必要としない場合は、how to get an Eval()
functionをC#で説明するインターネット上の場所もあります。
通常、アプリケーションにフックを提供するdllをユーザーに提供することでこれを行います。これにより、アプリケーションがロードできるDLLを作成することができます。 – mikerobi
私は、単に.csファイルをディレクトリにドロップし、コンパイルして実行できるようにしたプログラムを使用しました。 – JamieB
ここでDarin Dimitrovの答えをご覧ください:http://stackoverflow.com/questions/4718329/compiling-code-dynamically-using-c-sharp –