1

ASP.NET MVC 4C#およびを使用してAutoMapperいます。私の global.asax.cs で、別のプロジェクト (私の Web アプリで参照されている C# プロジェクト) からマッピングを登録しようとしています。

この他のプロジェクトには、マッピングがあります。サンプル クラスは次のとおりです。

namespace MyProject.Web.Core.Mappings
{
     public class EmployeeMapping
     {
          public EmployeeMapping()
          {
               Mapper.CreateMap<Employee, EmployeeInfoViewModel>();
          }
     }
}

私のglobal.asax.csには、これらのマッピングをロードしたいメソッドがあります。以下のコードはオンラインになりましたが、マッピング クラス (この場合は EmployeeMapping) を取得していません。

protected void AutoMapperConfig()
{
     string mappingNamespace = "MyProject.Web.Core.Mappings";

     var q = from t in Assembly.GetAssembly(typeof(string))
             where t.IsClass && t.Namespace == mappingNamespace
             select t;

     q.ForEach(t => Debug.WriteLine(t.Name));
}

(Web プロジェクト以外の別のプロジェクトから) 特定の名前空間でクラスを取得して使用するにはどうすればよいActivator.CreateInstanceですか?

私が欲しいのは、指定された名前空間で指定されているクラスのリストだけです。

4

2 に答える 2

3

(Web プロジェクト以外の別のプロジェクトから) 特定の名前空間でクラスを取得し、Activator.CreateInstance を使用するにはどうすればよいですか?

アセンブリ内の型の1 つを知っていると仮定すると、次を使用できます。

var types = typeof(TheTypeYouKnowAbout).Assembly.GetTypes()
                .Where(t => t.Namespace == "TheNamespaceYouWant");
                // Possibly add more restrictions, e.g. it must be
                // public, and a class rather than an interface, and
                // must have a public parameterless constructor...
foreach (var type in types)
{
    // Do something with the type
}

(何をしようとしているのかについてより多くの情報を提供できる場合は、より詳細に支援することが容易になります。)

于 2012-11-16T07:43:46.517 に答える
0

を呼び出すとAssembly.GetAssembly(typeof(string))、mscorlib.dll に型が読み込まれ、指定した linq クエリからは何も返されません。特定のアセンブリの型を照会するには、ortypeof(EmployeeMapping).Assemblyを使用してアセンブリを読み込む必要があります。Assembly.GetAssembly(typeof(EmployeeMapping))Assembly.LoadFrom("YourAssemblyName.dll")

編集:

あなたの質問にさらに答えるために...マッピングを担当するすべてのタイプとそれらが含まれているアセンブリを知っていると仮定します。

protected void AutoMapperConfig()
{
    const string mappingNamespace = "MyProject.Web.Core.Mappings";

    //There are ways to accomplish this same task more efficiently.
    var q = (from t in Assembly.LoadFrom("YourAssemblyName.dll").GetExportedTypes()
             where t.IsClass && t.Namespace == mappingNamespace
             select t).ToList();

    //Assuming all the types in this namespace have defined a
    //default constructor. Otherwise, this iterative call will
    //eventually throw a TypeLoadException (I believe) because
    //the arguments for any of the possible constructors for the
    //type were not provided in the call to Activator.CreateInstance(t) 
    q.ForEach(t => Activator.CreateInstance(t));
}

ただし、Web プロジェクトでアセンブリを参照している場合...コンパイル時に型が不明な場合は、以下またはある種の IoC/DI フレームワークを使用してマッピング クラスをインスタンス化します。

protected void AutoMapperConfig()
{
    Mapper.CreateMap<Employee, EmployeeInfoViewModel>();
    //Repeat the above for other "mapping" classes.
    //Mapper.CreateMap<OtherType, OtherViewModel>();
}

編集 @Brendan Vogt コメントの最初に与えられたもの:

public interface IMappingHandler
{
}

//NOTE: None of this code was tested...but it'll be close(ish)..

protected void AutoMapperConfig()
{
    //If the assemblies are located in the bin directory:
    var assemblies = Directory.GetFiles(HttpRuntime.BinDirectory, "*.dll");

    //Otherwise, use something like the following:
    var assemblies = Directory.GetFiles("C:\\SomeDirectory\\", "*.dll");

    //Define some sort of other filter...a base type for example.
    var baseType = typeof(IMappingHandler);

    foreach (var file in assemblies)
    {
        //There are other ways to optimize this query.
        var types = (from t in Assembly.LoadFrom(file).GetExportedTypes()
                     where t.IsClass && !t.IsAbstract && baseType.IsAssignableFrom(t)
                     select t).ToList();

        //Assuming all the queried types defined a default constructor.
        types.ForEach(t => Activator.CreateInstance(t));
    }
}
于 2012-11-16T07:50:47.617 に答える