2012-06-04 2 views
4

Я хочу цикл по всем классам, которые я добавил в моем проектеПолучить все классы, созданного пользователь в AppDomain.CurrentDomain

Assembly[] foo = AppDomain.CurrentDomain.GetAssemblies(); 

foreach(Assembly a in foo) 
{     
    foreach(Type t in a.GetTypes()) 
    { 

    } 
} 

это то, что я пытался, но я хочу, чтобы исключить узлы, которые предоставляются .net, например, «mscorlib»

+0

Извините, кажется, вы забыли задать вопрос. – leppie

+0

Я хочу исключить сборки, предоставленные .net - мой пример взял все сборки - если вам нужен вопрос для этого: как я могу это достичь? – Jan

ответ

7

Одно общее решение будет фильтровать сборки по имени, если все ваши сборках имеют общий префикс (если у вас есть более или менее уникальный префикс).

var foo = AppDomain.CurrentDomain.GetAssemblies() 
           .Where(a=>a.FullName.StartsWith("MyProject.")); 

Если вы заинтересованы только в некоторых конкретных типов, рассмотреть возможность использования attributes для классов, или даже добавить один на уровне сборки.

Пример:

Создать атрибут:

[AttributeUsage(AttributeTargets.Assembly)] 
public class MyAssemblyAttribute : Attribute { } 

добавить следующее к AssemblyInfo.cs:

[assembly: MyAssemblyAttribute()] 

и отфильтровать узлы, которые вы ищете по адресу:

var foo = AppDomain.CurrentDomain 
        .GetAssemblies() 
        .Where(a => a.GetCustomAttributes(typeof(MyAssemblyAttribute), false).Any()); 

Также вы найдете at this question. В one answer предлагается проверить полное имя каждого узла, но это довольно утомительно, например:

//add more .Net BCL names as necessary 
var systemNames = new HashSet<string> 
{ 
    "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 
    "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
    ... 
}; 

var isSystemType = systemNames.Contains(objToTest.GetType().Assembly.FullName); 

Это всегда легче пометить узлы (по имени или атрибута), чем пытаться определить, какие из них являются часть .Net framework.

+1

Также лучше пометить собственные сборки, потому что вы можете не захотеть * любых * сторонних сборок. Скорее всего, сборки .NET Framework - это не единственные сборки с кодом, который вы не контролируете в своем проекте. Вы также должны сделать атрибут 'internal' и убедиться, что он открыт только для ваших других сборок. Таким образом, другие сборки, которые вы не укажете, не могут использовать ваш атрибут. – casperOne

+0

есть ли способ найти все типы, которые используют определенный тип? например, я хочу, чтобы все типы имели isntance StringBuilder. – Jan

+0

без пометки с атрибутом! – Jan

0

Проверьте следующие свойства для типа внутреннего контура.

t.GetType().Namespace == "System" 
t.GetType().Namespace.StartsWith("System") 
t.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary" 
+0

Это действительно не работает, поскольку я могу легко определить типы в пространстве имен 'System'. – casperOne

+0

Но я думаю, что свойство ScopeName поможет. –

+0

@Romil No. Не все типы .Net framework являются частью mscorlib. Поэтому ScopeName не всегда является CommonLanguageRuntimeLibrary. – sloth

1

В одном из моих проектов мне нужен список классов, используемых в качестве бизнес-объектов. Эти классы всегда являются создаваемыми пользователем типами, но могут быть в ссылочной сборке. Они не реализуют определенный интерфейс и не выходят из определенного базового класса и не имеют отличительного атрибута.

Это код, я использую для фильтрации полезных типов:

return 
    type.IsClass && // I need classes 
    !type.IsAbstract && // Must be able to instantiate the class 
    !type.IsNestedPrivate && // Nested private types are not accessible 
    !type.Assembly.GlobalAssemblyCache && // Excludes most of BCL and third-party classes 
    type.Namespace != null && // Yes, it can be null! 
    !type.Namespace.StartsWith("System.") && // EF, for instance, is not in the GAC 
    !type.Namespace.StartsWith("DevExpress.") && // Exclude third party lib 
    !type.Namespace.StartsWith("CySoft.Wff") && // Exclude my own lib 
    !type.Namespace.EndsWith(".Migrations") && // Exclude EF migrations stuff 
    !type.Namespace.EndsWith(".My") && // Excludes types from VB My.something 
    !typeof(Control).IsAssignableFrom(type) && // Excludes Forms and user controls 
    type.GetCustomAttribute<CompilerGeneratedAttribute>() == null && // Excl. compiler gen. 
    !typeof(IControllerBase).IsAssignableFrom(type); // Specific to my project 

Поскольку мои пользователь не в GAC !type.Assembly.GlobalAssemblyCache делает довольно хорошую работу в исключении большинства BCL (Framework библиотеки) типов и некоторые третьи -партийный материал.

Это не водонепроницаемый, но хорошо работает мой случай. Скорее всего, вам потребуется настроить его для ваших нужд.