1)短い答え:あなたがタイプをスクリプトで使用する予定のすべてのアセンブリにAddReferenceを追加する必要があります。
詳細: C#コンパイラは、依存ファイルの場所を推測しません。アセンブリファイルは、すべての依存関係への完全なパスを指定していません。名前だけが含まれているため、一般的にコンパイラがアセンブリファイルを見つけるのに十分ではありません。
詳細: 依存関係は2種類あります。コンパイル時の依存関係(a)とランタイム依存関係(b)と呼びます。
(a)アセンブリA.dllに「パブリッククラスA:B {}」、アセンブリB.dllに「パブリッククラスB {}」があり、スクリプトがAを使用しているとします。インスタンス: "新しいA()"コンパイラは、AがBから派生し、コンパイラが使用する各タイプの継承階層を解析する必要があるため、この場合はA.dllとB.dllの両方への参照を追加する必要があります。だからB.dllはあなたのスクリプトのコンパイル時の依存関係です - あなたのスクリプトを適切に解析するためには、コンパイラがそれを必要とします。
(b)別の例を考えてみましょう: "A.dllにpublicクラスA {publicオブジェクトM(){return new B();}}"と同じB.dllがあります。今度は "new A()。M()"をコンパイルするとき、Bの参照はメソッドMの本体でのみ発生し、コンパイラはインポートされたメソッドの本体を解析しないので、コンパイラはBについて知る必要はありません。この場合、スクリプトをコンパイルするために、A.dllへの参照を追加するだけで十分です。スクリプトが実行されると、メソッドMが呼び出されます。その時点でCLRはアセンブリBをロードします。これは少し複雑になるため、詳細はスキップしますが、一般的なシナリオではアセンブリを見つけることができます。参照を明示的に追加する必要はありません。
2)アセンブリオブジェクトを受け取るAddReferenceのオーバーロードを使用することをお勧めします。次のようなものがあります。 engine.AddReference(typeof(SomeTypeInAssemblyFoo).Assembly)は、型SomeTypeInAssemblyFooを含むアセンブリFooをロードします。
3)単純なものではありません。 Reflection APIまたはRoslyn APIを使用してすべての参照を列挙し、それぞれをロードすることができます。
説明が明確でない場合や詳細を知りたい場合は、お気軽にご質問ください。
優れた回答、+1! – GETah