1

StructureMap を使用してランタイム型の登録を実行しようとしていますが、Type.GetType(). テストアプリの完全なコードは次のとおりです。

using System;
using System.Collections.Generic;
using System.Linq;
using StructureMap;
using StructureMap.Configuration.DSL;
using StructureMap.Graph;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            ObjectFactory.Initialize(r => r.Scan(
                s => {
                    s.AssembliesFromPath(
                        @"c:\Path\To\MyClasses\bin\Debug");
                    s.Convention<MyConvention>();
                }
                                              ));

            ObjectFactory.AssertConfigurationIsValid();

            foreach (var name in MyConvention.assemblyQualifiedTypenames) {
                Console.WriteLine(name);
                Console.WriteLine("Type found for reflection by assembly qualified name: {0}", Type.ReflectionOnlyGetType(name, false, false) != null);
                Console.WriteLine("Type found by assembly qualified name: {0}", Type.GetType(name) != null);
                Console.WriteLine("Type found by search: {0}",
                    AppDomain.CurrentDomain.GetAssemblies().ToList()
                    .SelectMany(assembly => assembly.GetTypes().Where(t => t.AssemblyQualifiedName == name))
                    .FirstOrDefault() != null
                );
            }
            Type type = null;
            foreach (var name in MyConvention.fullnames) {
                Console.WriteLine(name);
                Console.WriteLine("Type found by full name: {0}", Type.GetType(name) != null);
                Console.WriteLine("Type found by search: {0}",
                    AppDomain.CurrentDomain.GetAssemblies().ToList()
                    .SelectMany(assembly => assembly.GetTypes().Where(t => t.FullName == name))
                    .FirstOrDefault() != null
                );
            }
            foreach (var name in MyConvention.typenames) {
                Console.WriteLine(name);
                Console.WriteLine("Type found by name: {0}", Type.GetType(name) != null);
                Console.WriteLine("Type found by search: {0}",
                    (type = AppDomain.CurrentDomain.GetAssemblies().ToList()
                    .SelectMany(assembly => assembly.GetTypes().Where(t => t.Name == name))
                    .FirstOrDefault()) != null
                );
            }
            Console.ReadLine();
            var instance = ObjectFactory.GetInstance(type);
            Console.WriteLine("Type instance retrieved from StructureMap: {0}", instance != null);
            Console.ReadLine();
            ObjectFactory.WhatDoIHave()
                .Split(new [] { Environment.NewLine}, StringSplitOptions.None)
                .Where(s => s.Contains("Class2")).ToList()
                .ForEach(Console.WriteLine);
            Console.ReadLine();
        }

        private class MyConvention : IRegistrationConvention {
            public static List<string> typenames = new List<string>();
            public static List<string> fullnames = new List<string>(); 
            public static List<string> assemblyQualifiedTypenames = new List<string>(); 
            public void Process(Type type, Registry registry) {
                if (type.GetCustomAttributes(false).Any(o => o.GetType().Name == "MyClassAttribute")) {
                    registry.For(type).Use(type);
                    typenames.Add(type.Name);
                    fullnames.Add(type.FullName);
                    assemblyQualifiedTypenames.Add(type.AssemblyQualifiedName);
                }
            }
        }
    }
}

テストクラスの定義:

namespace MyAttributes {
    public class MyClassAttribute : Attribute { }
}

namespace MyClasses {
    public class MyClass1 { }

    [MyClass]
    public class MyClass2 { }
}

コンソール アプリの実行からの出力:

MyClasses.Class2、MyClasses、バージョン = 1.0.0.0、カルチャ = ニュートラル、PublicKeyToken = null
アセンブリ修飾名によるリフレクションで見つかった型: False
アセンブリ修飾名で見つかった型: False
検索で見つかったタイプ: True
MyClasses.Class2
フルネームで見つかった型: False
検索で見つかったタイプ: True
クラス2
名前で見つかった型: False
検索で見つかったタイプ: True

StructureMap から取得した型インスタンス: True

クラス 2 (MyClasses.Class2) 60eb30ad-ae50-413d-884f-04743ea3148c
  MyClasses.Class2、MyClasses、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null の構成済みインスタンス
                                         60eb30ad-ae50-413d-884f-04743ea3148c
  MyClasses.Class2、MyClasses、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null の構成済みインスタンス

この SO 投稿に基づいてすべてのテストを行いました- 何か基本的なことが欠けていますか?

4

2 に答える 2

1

このコードを試してください。これにより、アセンブリ修飾名の使用が回避されるため、バージョン管理のためのハードコーディングはありません。

const string myClass = "<Namespace.Class>";
const string dllName = "<DllName>,"; //Notice the ','

Type myType = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.ToString().StartsWith(dllName)).Select(a => a.GetType(myClass )).FirstOrDefault();
于 2014-10-09T23:25:57.747 に答える
1

問題は、 を使用して型を取得しようとしていることですType.GetType(name)。したがって、.net は、GAC または実行中のアセンブリと同じディレクトリのいずれかで、アセンブリ自体を見つけようとします。別のディレクトリにあるため、見つけることができません。MyClassesこれを確認するには、含まれている実行可能ファイルをコンソール アプリと同じディレクトリにコピーします。その後、動作します。

同様の理由でAppDomain.CurrentDomain.GetAssemblies()、現在のドメインでは何も使用されていないため、含まれませんMyClasses

から返されたアセンブリをロードしてからMyConvention.assemblyQualifiedTypenamesを使用するか、ここに記載されているように独自のアセンブリ リゾルバーを指定できるassembly.GetType(name)バージョンを使用する必要があります(これは、クラスにアセンブリ名が含まれている場合にのみ機能します)。Type.GetType

于 2012-07-01T07:02:56.007 に答える