インターフェイス(「インターフェイス」という名前のアセンブリ内。プロジェクト内:-インターフェイス)
namespace Interfaces
{
public interface IDoSomeWork1
{
string DoSomeWork1();
}
}
namespace Interfaces
{
public interface IDoSomeWork2
{
string DoSomeWork2();
}
}
依存関係(「エンティティ」という名前のアセンブリ内。プロジェクト内:-エンティティ)
namespace Entities
{
public class ClassB : IDoSomeWork1
{
public string DoSomeWork1()
{
return this.ToString();
}
}
}
namespace Entities
{
public class ClassC : IDoSomeWork2
{
public string DoSomeWork2()
{
return this.ToString();
}
}
}
クラス(プロジェクト内:-UsingUnity)
public class ClassA
{
[Dependency]
public IDoSomeWork1 DoSomeWork1 { get; set; }
[Dependency]
public IDoSomeWork2 DoSomeWork2 { get; set; }
public void SomeMethodInClassA()
{
Console.WriteLine(DoSomeWork1.DoSomeWork1());
Console.WriteLine(DoSomeWork2.DoSomeWork2());
}
}
App.Config(コンソールアプリケーションプロジェクトの場合:-ConsoleUsingUnity)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container>
<types>
<type type="Interfaces.IDoSomeWork1, Interfaces"
mapTo="Entities.ClassB, Entities" />
<type type="Interfaces.IDoSomeWork2, Interfaces"
mapTo="Entities.ClassC, Entities" />
</types>
</container>
</containers>
</unity>
</configuration>
クライアント(コンソールアプリケーションプロジェクトの場合:-ConsoleUsingUnity)
public class Class1
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
// Load from config file
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(container);
ClassA classA = container.Resolve<ClassA>();
classA.SomeMethodInClassA();
}
}
クライアントを実行すると、section.Configure(container);で次のエラーが発生します。
指定されたアセンブリ名またはコードベースが無効でした。 (HRESULTからの例外:0x80131047)
設定やタイプに問題があるかどうかはわかりません。誰かがここで間違いを指摘できますか?
私の質問に答える前に、上に投稿されたコードは私に問題(ビルドエラーなど)を与えなかったことを述べなければなりません。それはちょうど私が私の質問で述べたエラーを私に与えました。この時点でのUnityの問題は、ロードできないアセンブリまたはアセンブリ内のタイプを提供しないことです。これは 要求された機能 です。
私の場合、それはアセンブリの欠落の問題でした。クライアントアプリケーションプロジェクトでエンティティアセンブリを参照しませんでした。 「エンティティ」アセンブリは実行時にのみ解決できたようです(コンパイル時エラーが発生しなかったため)。ただし、実行時エラーもまったく役に立ちませんでした。
Fusion Log Viewer (。NET SDKフォルダーにあるはずです)を見てみました。なんてユーティリティの逸品なのでしょう。あらゆる種類のアセンブリバインディング(すべてまたは失敗のみ)をログに記録でき、アセンブリをロードできなかった非常にわかりやすい説明を提供します。非常に役立ちます!
したがって、次回、この「指定されたアセンブリ名またはコードベースが無効でした」というエラーが発生した場合は、Fusion LogViewerを試してください。ロードできなかったタイプを見つけるのに役立ちません。ただし、少なくとも、すべてのアセンブリが正しく読み込まれていることを確認できます。
他の誰かが同じ問題を抱えている場合-私もこのエラーを受け取りましたが、少し異なる問題がありました。次のように明確に存在するアセンブリをロードしようとしました。
Assembly.Load("C:\\Program Files\\MyProgram\\MyAssembly.dll");
試行錯誤の末、パスを通過することは想定されておらず、.dll
拡張子を含めることも想定されていないことがわかりました。以下は私の問題を修正しました:
Assembly.Load("MyAssembly");
うまくいけば、それは遅かれ早かれ他の誰かを助けるでしょう!
ドメインに接続すると AssemblyResolve イベントで、バインドに失敗したアセンブリを取得できます。
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
Web.configファイルが存在するプロジェクトに、欠落しているアセンブリのアセンブリ参照が追加されていることを確認してください。
これを見逃していた。 Unityを使用してクラスを解決していたプロジェクトにこれらのアセンブリ参照を既に追加しましたが、構成ファイルが配置されている親プロジェクトに追加できませんでした。これで私の問題は解決しました。
どのType
が正確にバインドに失敗したかを見つけるための最も時間のかからない方法は、次のとおりです。
DEBUG
バージョンのUnity
およびUnity.Configuration
をビルドします(プロジェクトでより多くのUnityアセンブリを使用する場合は、それらもビルドします)Debug > Exceptions
に移動し、Common Language Runtime Exceptions
にThrown
列のチェックボックスがあることを確認します。今、そのことをクラッシュさせに行きます。 UnitysのTypeResolverImpl.SearchAssemblies
メソッドで実行が停止し、typeNameOrAlias
パラメーターが答えを保持します!
このように動作します
Dim dllData = System.IO.File.ReadAllBytes(dllFullPath)
Dim asb As System.Reflection.Assembly
asb = System.Reflection.Assembly.Load(dllData)
Dim cls As Object = asb.CreateInstance("namespace.class")