これは非常に長いものです。
Core.dll (以下を参照) を参照すると、アプリケーションは type の新しいオブジェクトを作成し、Core
その際、コンストラクターはフォルダーをスキャンして、インターフェイスC:\Problems
を使用する型を含む DLL を探すという考え方です。IPlugin
コンソール アプリケーションから Core.dll を参照すると機能します。Core.dll が GAC にない限り、PowerShell から同等の操作を行っても機能しません。
詳細は次のとおりです。
次の結果であるアセンブリ(Core.dll)があります。
public class Core
{
List<IPlugin> plugins = new List<IPlugin>();
public Core(string path)
{
LoadPlugins(path);
foreach (IPlugin plugin in plugins)
plugin.Work();
}
void LoadPlugins(string path)
{
foreach (string file in Directory.GetFiles(path))
{
FileInfo fileInfo = new FileInfo(file);
Assembly dllAssembly = Assembly.LoadFile(file);
foreach (Type type in dllAssembly.GetTypes())
{
Type typeInterface = type.GetInterface("Problems.IPlugin");
if (typeInterface != null)
plugins.Add((IPlugin)Activator.CreateInstance(
dllAssembly.GetType(type.ToString())));
}
}
}
}
public interface IPlugin
{
string Name {get; set;}
void Work();
}
次に、以下を含む別のアセンブリ MyPlugin.dll があります。
public class MyPlugin : IPlugin
{
public string Name { get; set; }
public void Work()
{
Console.WriteLine("Hello, World. I'm a plugin!");
}
}
これをすべて 3 番目のプロジェクト TestApp.exe (参照として Core.dll を使用) でテストしました。
static void Main(string[] args)
{
Core core = new Core(@"C:\Problems");
Console.ReadLine();
}
Core.dll と MyPlugin.dll の両方を C:\Problems に配置すると、TestApp.exe が魅力的に機能します。そこで、次の PowerShell スクリプトを作成します。
Add-Type -Path "C:\Problems\Core.dll"
$core = New-Object Problems.Core "C:\Problems"
これが私の結果です (赤の束を想像してください):
New-Object : Exception calling ".ctor" with "1" argument(s): "Unable to load one or more o
f the requested types. Retrieve the LoaderExceptions property for more information."
At line:1 char:11
+ New-Object <<<< Problems.Core "C:\Problems"
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
例外をドリルダウンすると、次のことがわかります。
PS C:\Problems> $Error[0].Exception.InnerException.LoaderExceptions
Could not load file or assembly 'Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
これまでの私の結論は、プラグイン ローダーの一部として GetTypes() を実行しているときに、MyPlugin が Problems.IPlugin を継承していることがわかりますが、どこにあるのかわかりません。でも、すでに Core.dll にロードしていませんか?
これを回避できる唯一の方法は、Core.dll アセンブリに署名して GAC に追加することですが、これは煩わしく、私の目的には合いません。
(すべてのクラスは Problems 名前空間にあり、問題を説明するために大量のクリーンアップとフィルタリングのロジックを省略しました。)