プロジェクトに追加したすべてのクラスをループしたい
Assembly[] foo = AppDomain.CurrentDomain.GetAssemblies();
foreach(Assembly a in foo)
{
foreach(Type t in a.GetTypes())
{
}
}
これは私が試したものですが、.netによって提供されるアセンブリ(たとえば「mscorlib」)を除外したいと思います。
プロジェクトに追加したすべてのクラスをループしたい
Assembly[] foo = AppDomain.CurrentDomain.GetAssemblies();
foreach(Assembly a in foo)
{
foreach(Type t in a.GetTypes())
{
}
}
これは私が試したものですが、.netによって提供されるアセンブリ(たとえば「mscorlib」)を除外したいと思います。
一般的な解決策の1つは、すべてのアセンブリに共通のプレフィックスがある場合(多かれ少なかれ一意のプレフィックスがある場合)、名前でアセンブリをフィルタリングすることです。
var foo = AppDomain.CurrentDomain.GetAssemblies()
.Where(a=>a.FullName.StartsWith("MyProject."));
特定のタイプのみに関心がある場合は、クラスに属性を使用することを検討するか、アセンブリレベルで属性を追加することもできます。
例:
属性を作成します。
[AttributeUsage(AttributeTargets.Assembly)]
public class MyAssemblyAttribute : Attribute { }
AssemblyInfo.csに以下を追加します。
[assembly: MyAssemblyAttribute()]
見ているアセンブリをフィルタリングします。
var foo = AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => a.GetCustomAttributes(typeof(MyAssemblyAttribute), false).Any());
また、あなたはこの質問で面白いと思うでしょう。1つの回答では、各アセンブリの完全修飾名を確認することをお勧めしますが、これは非常に面倒です。例:
//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);
アセンブリを(名前または属性で)マークする方が、.NetFrameworkの一部であるアセンブリを特定するよりも常に簡単です。
私のプロジェクトの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(フレームワークライブラリ)タイプと一部のサードパーティのものを除外するのにかなり良い仕事をしています。
これは防水ではありませんが、私の場合はうまく機能します。ほとんどの場合、ニーズに合わせて微調整する必要があります。
タイプイン内部ループの次のプロパティを確認します。
t.GetType().Namespace == "System"
t.GetType().Namespace.StartsWith("System")
t.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary"