5

通常、アプリケーションではMicrosoft.Practices.Unity.dllのみを参照します。基本的な機能のみを使用しており、これは正常に機能します。あるアプリケーションでは、リフレクションを使用するという行為により、Unityは別のDLLを必要とします。

たとえば、コンソールアプリを作成し、Microsoft.Practices.Unity(ファイルバージョン2.0.414.0)のみを参照します。次のコードを入力して実行します。

class Program
{
    static void Main()
    {
        using (var container = new UnityContainer())
        {
            container.RegisterType<IDoSomething, ConcreteDoSomething>();

            var thing = container.Resolve<IDoSomething>();

            thing.DoSomething();
            Console.WriteLine();

            LoadSchemaLoaders();
        }
    }

    public static void LoadSchemaLoaders()
    {
        var type = typeof(ISchemaLoader);

        try
        {
            // Get all loaded assemblies, including Unity.
            // Get all of the types.
            // Filter for types that ISchemaLoader (custom type) can be assigned from.

            var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(s => s.GetTypes())
                .Where(c => type.IsAssignableFrom(c) && c.IsClass && !c.IsAbstract && !c.IsGenericParameter);

            Console.WriteLine("Got here...");

            types.FirstOrDefault();
        }
        catch (ReflectionTypeLoadException ex)
        {
            Console.WriteLine(ex.Message);

            foreach (Exception exSub in ex.LoaderExceptions)
            {
                Console.WriteLine(exSub.Message);
            }
        }
    }
}

public interface IDoSomething
{
    void DoSomething();
}

public class ConcreteDoSomething : IDoSomething
{
    public void DoSomething()
    {
        Console.WriteLine("Something!");
    }
}

public interface ISchemaLoader {}

私のマシンでは、出力は次のとおりです。

何か!

ここに着きました...
要求されたタイプの1つ以上をロードできません。詳細については、LoaderExceptionsプロパティを取得してください。
ファイルまたはアセンブリ'Microsoft.Practices.ServiceLocation、Version = 1.0.0.0、Culture = neutral、PublicKeyToken=31bf3856ad364e35'またはその依存関係の1つを読み込めませんでした。システムは、指定されたファイルを見つけることができません。

行をコメントアウトします

LoadSchemaLoaders();

もう一度実行すると、機能します。

これは、製品コードの簡略化されたバージョンです。プロダクションコードは、実際にはインターフェイスを実装するカスタムタイプを動的にロードしています。Unityを導入するとすぐに、コードは例外をスローしました。しかし、Unityタイプは私たちのインターフェースを実装できません!

アセンブリを単純に反映することで、コアUnityアセンブリに別の依存関係が必要になる理由がわかりません。

4

1 に答える 1

7

Microsoft.Practices.ServiceLocation(おそらくIServiceLocator)で定義されたインターフェイスからのUnityアセンブリのタイプ。

コンパイラーは、アプリケーションがそのdllを直接参照する必要はありません...しかし、System.Typeオブジェクトを反映すると、Unityによって参照されるdllをロードしようとします。

これがアセンブリを熟考するときにのみ発生する理由は、Unityが通常の状況でMicrosoft.Practices.ServiceLocationを参照するタイプをロードしない可能性があるためです。

回避策として、Assembly.GetTypes()呼び出しをtry/catchブロックで囲むことができます。

または、Microsoft.Practices.ServiceLocation dllをアプリケーションが検出できる場所に配置すると、問題も解決するはずです。

于 2012-04-06T22:49:23.710 に答える