2012-11-16 2 views
1

ASP.NET MVC 4, C#AutoMapper을 사용하고 있습니다. 내 global.asax.cs에서 다른 프로젝트 (내 웹 응용 프로그램에서 참조 된 C# 프로젝트)에서 내 매핑을 등록하려고합니다. 나는 이러한 매핑을로드 할 방법이 내 global.asax.cs에서웹 프로젝트 외부의 어셈블리에서 클래스 가져 오기

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

: 내 매핑이이 다른 프로젝트에서

, 여기에 샘플 클래스입니다. 나는 아래의 코드를 온라인으로 가지고 있지만,이 경우 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)); 
} 

이 어떻게 (웹 프로젝트 이외의 다른 프로젝트에서) 특정 네임 스페이스에 내 수업을받을 수 있나요 및 Activator.CreateInstance을 사용 하시겠습니까?

내가 원하는 것은 주어진 네임 스페이스에 지정된 클래스의 목록입니다.

답변

3

웹 프로젝트가 아닌 다른 프로젝트의 특정 네임 스페이스에서 클래스를 가져오고 Activator.CreateInstance를 사용합니까?

당신이 어셈블리의 형식 하나을 알고 가정하면 사용할 수 있습니다

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 
} 

을 (당신이 당신이하려는 일에 대해 더 많은 정보를 제공 할 수 있다면, 쉽게 될 것입니다

+0

? 이들은 모두 수업입니다. –

+1

@BrendanVogt : 클래스 *는 * 유형입니다 - 클래스 만 원하면't.IsClass'를 다른 필터로 사용하십시오. –

+0

나는 내가 TheType의 장소에 무엇을 넣어야하는지 의미했다. 당신은 알고 있는가? –

0

Assembly.GetAssembly(typeof(string))을 호출하면 mscorlib.dll에 유형이로드되고 입력 한 linq 쿼리에서 아무 것도 반환되지 않습니다. 해당 어셈블리의 형식을 쿼리하려면 typeof(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)); 
} 

하지만 당신이 있다면 웹 프로젝트에서 어셈블리를 참조하는 ... 컴파일 유형을 알 수없는 경우 아래 또는 일종의 IoC/DI 프레임 워크를 사용하여 매핑 클래스를 인스턴스화합니다.

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

편집을 감안할 때 @Brendan 보그의 첫 번째 댓글 : 당신은 종류에 따라 무슨 소리

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)); 
    } 
} 
+0

@Jon Skeet의 답변에서 메모를 추가하십시오. Assembly.GetTypes()는 어셈블리 (공개, 개인, 내부 등)에 포함 된 모든 유형을로드합니다. Assembly.GetExportedTypes()를 호출하면 public 유형 만 반환됩니다. –

+0

다른 매핑 클래스가 있기 때문에 EmployeeMapping과 같은 클래스 이름을 지정하고 싶지 않습니다. 코드가 너무 많습니다. .dll도 지정하고 싶지 않습니다. 왜냐하면이 프로젝트 외에 다른 프로젝트에 매핑 클래스가 있다면 어떻게 될까요? –

+0

@Brendan Vogt, 위의 편집을 참조하십시오. –

관련 문제