rksoftware

Visual Studio とか C# とかが好きです

C# で参照で追加したプロジェクトのクラスが見つからない

少し詳しく表現すると、参照で追加したプロジェクトのクラスの定義されている Assembly (追加したプロジェクト) がロードされていない、です。

例えば次のように ClassLibrary1 プロジェクトを参照しているものとします。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" />
  </ItemGroup>

</Project>

■ コード

コードを動かしてみるのが分かりやすいでしょう。次のコードは Assembly を一覧して、参照している Assembly (プロジェクト) のクラスを使って、Assembly を一覧しています。

foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
  Console.WriteLine(asm.FullName);

Console.WriteLine("====================");

var class1 = Activator.CreateInstance("ClassLibrary1", "ClassLibrary1.Class1").Unwrap();
Console.WriteLine(class1.GetType().FullName);

Console.WriteLine("====================");

foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
    Console.WriteLine(asm.FullName);

実行結果(例)

System.Private.CoreLib, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
ConsoleApp1, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null
System.Runtime, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Runtime.Extensions, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Console, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
====================
ClassLibrary1.Class1
====================
System.Private.CoreLib, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
ConsoleApp1, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null
System.Runtime, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Runtime.Extensions, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Console, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Threading, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Text.Encoding.Extensions, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
ClassLibrary1, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null
netstandard, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX

参考

クラスを使うまで Assembly がいないのが確認できます。また、名前が分かっていればクラスを使うことができることも確認できます。しかし、これでは未知の名前のクラスを使うことができません。

■ Assembly の位置と名前が分かってれば

Assembly の位置と名前が分かってれば Assembly.LoadFrom(string) メソッドが使えます。

System.Reflection.Assembly.LoadFrom("ClassLibrary1");

foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
  Console.WriteLine(asm.FullName);

Console.WriteLine("====================");

var class1 = Activator.CreateInstance("ClassLibrary1", "ClassLibrary1.Class1").Unwrap();
Console.WriteLine(class1.GetType().FullName);

Console.WriteLine("====================");

foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
    Console.WriteLine(asm.FullName);

実行結果(例)

System.Private.CoreLib, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
ConsoleApp1, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null
System.Runtime, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Runtime.Extensions, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Console, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
ClassLibrary1, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null
====================
ClassLibrary1.Class1
====================
System.Private.CoreLib, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
ConsoleApp1, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null
System.Runtime, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Runtime.Extensions, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Console, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Threading, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
System.Text.Encoding.Extensions, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX
ClassLibrary1, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null
netstandard, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX

参考

クラスを使う前にクラスライブラリの Assembly (プロジェクト) が読まれました。