2014-01-03 4 views
2

Я пытаюсь получить класс и методы из сборки, он работает, когда сборка такая же, где находится класс, но когда она не работает, когда сборка находится в другом проекте. Я уже добавляю ссылку из проекта, я хочу получить класс и методы, но var theList возвращает null. Я хочу получить класс и методы от одного proyect к другому, 2 proyects находятся в одном решении. Мне нужна помощьПолучение классов из пространства имен

class Program 
{ 
    static void Main(string[] args) 
    { 

     var theList = Assembly.GetExecutingAssembly().GetTypes().ToList().Where(t => t.Namespace == "____mvc4.Models").ToList(); 

     Console.WriteLine("--List of Classes with his respective namescpace : "); 
     foreach (var item in theList) 
     { 

      Console.WriteLine(item); 

     } 
     Console.WriteLine("------List of classes: "); 
     foreach (var item in theList) 
     { 

      Console.WriteLine("*****************" + item.Name + "*****************"); 
      MemberInfo[] memberInfo = item.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Instance); 
      for (int i = 0; i < memberInfo.Length; i++) 
      { 
       if (!(memberInfo[i].Name.Contains("get_") || memberInfo[i].Name.Contains("set_"))) 
       { 
        Console.WriteLine("{0}", memberInfo[i].Name); 
       } 

      } 

     } 

     Console.ReadLine(); 
    } 

return null

enter image description here

asembly где классы, которые я хочу получить не появляется в AppDomain.CurrentDomain.GetAssemblies() ToList().

enter image description here

+0

Что произойдет, если вы сделаете это без 'Where()' положение и вручную посмотреть результаты? Почему, по-вашему, пространство имен является '____ mvc4.Models'? –

+0

И 'theList' действительно' null', или это пустой список? –

+0

, если я делаю это без предложения where(), возвращает класс и метод из собственной сборки. Var theList пуст и ____ mvc4.Models - это пространство имен, где находятся классы и методы, которые хотят список @PhilipKendall –

ответ

1

Здесь ...

var theList = Assembly.GetExecutingAssembly().GetTypes()...etc 

вы имеете в виду текущего ("ВЫПОЛНЕНИЕ") в сборе. Если вы хотите получать типы из другой сборки, вам нужно получить ссылку на эту сборку. Простой способ сделать так, чтобы ссылаться на некоторый тип из этого ссылочного узла:

var otherAssembly = typeof(SomeTypeDefinedInAReferencedAssembly).Assembly; 
var theList = otherAssembly.GetTypes()...etc 
+0

Я пробую это, но получить это исключение «Невозможно загрузить один или несколько типов. Восстановить свойство LoaderExceptions для получения дополнительной информации» @Heinzi –

+0

@ user1629278: А что говорит свойство LoaderException? – Heinzi

1

Если вы пытаетесь сделать это в общем, как это возможно, не зная или заботы, какие сборки содержат это пространство имен, вам нужно проверить загруженные модули:

var theList = new List<Type>(); 
BuildManager.GetReferencedAssemblies(); 
var modules = Assembly.GetExecutingAssembly().GetLoadedModules(); 
theList.AddRange(modules.SelectMany(x => x.Assembly.GetTypes().Where(t => t.Namespace == "____mvc4.Models"))); 
+0

Единственная проблема, которую я нашел с помощью 'GetLoadedModules', - это то, что .NET будет собирать сборки JIT. Поэтому, если эта сборка еще не была использована, она не будет в списке «LoadedModules», что означает, что вы пропускаете сборки. Я мог ошибаться, но я верю, что именно поэтому я пошел с «AppDomain». Просто стоит отметить. Надеюсь, этот комментарий поможет. –

+0

Это хороший момент, и тем более причина иметь этот улов в вашем примере, поскольку могут быть исключения, возникающие при загрузке сборки по разным причинам, кроме ошибок при разрешении/безопасности. – Matt

+0

по-прежнему возвращает пустой список @tencntraze –

1

Если вы хотите сделать это динамически, то вы должны получить все узлы в текущем домене или итерируют/bin/каталог. Домен предоставит вам все виды сборок, включая ваши стандартные, например, System./bin/ограничит вас только вашими обычными вещами.

Вот утилита, которую я использую. Вы проходите оценку - то есть фильтр - и он возвращает список типов.

public static List<Type> GetClassesWhere(Func<Type, bool> evaluator) 
    { 
     var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); 

     var types = new List<Type>(); 

     foreach(var assembly in assemblies) 
     { 
      try 
      { 
       types.AddRange(assembly.GetTypes().Where(evaluator).ToList()); 
      } 
      catch 
      { 
      } 
     } 

     return types; 
    } 

Стараюсь/поймать каждый узел по отдельности, потому что я обнаружил, что иногда я получаю некоторые странные ошибки нет прав, особенно в общих средах, таких как Azure и AppHarbor. Это всегда было на собраниях, на которых меня все равно не волновало, поэтому я не принимаю никаких мер по улову. Для моих пользовательских сборок это всегда работает для меня.

В вашем примере, вы бы использовать его константы выглядит (если вы поместите его в статическом классе под названием Utilities)

var types = Utilities.GetClassesWhere(t => t.Namespace == "____mvc4.Models"); 
+0

Я пробую это, и var types возвращает NULL @Eli Gassert –

+0

Это невозможно. Пустой список, возможно, но не null. Вы можете видеть в моем коде, что он всегда возвращает * something * и никогда не имеет значения null. –

+0

Извините, что вы правы, возвращает пустой список @Eli Gassert –

-2
AppDomain.CurrentDomain.GetAssemblies() 
         .SelectMany(am => am.GetTypes()) 
         .Select(a => a.Namespace == "Name of your namespace") 
         .Distinct(); 
Смежные вопросы