Martin
Martin

Reputation: 2235

c# - Get a list of Type objects from another DLL

I have a web app that uses 2 custom DLLs. One is a mini-ORM I made on top of Dapper and the other is a class library containing all my model classes. My ORM has a class that runs at startup, scans a provided package for types and builds a field registry for the ORM to use. This class used to be in the same class library as the models and it worked perfectly since it was able to find the classes within its own class library. Ever since I moved it to the ORM library, it (predictably) stopped working because of this line :

var types = Assembly.GetAssembly()
            .GetTypes()
            .Where(t => t.IsClass)
            .Where(t => t.Namespace != null)
            .Where(t => t.Namespace.StartsWith(packageName));

I tried replacing GetAssembly() by GetEntryAssembly() thinking the calling web app would encapsulate all the model classes it found in the models library but it looks like I was wrong.

My question in a nutshell is : Is there a way to access types contained in a DLL from a different DLL through a parent web app that references both?

Upvotes: 2

Views: 813

Answers (1)

Sherif Elmetainy
Sherif Elmetainy

Reputation: 4472

Yes it is possible, but the way depends on your application.

You can search for types in all loaded assemblies

var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(a => a.GetTypes())
    .Where(t => t.IsClass)
    .Where(t => t.Namespace != null)
    .Where(t => t.Namespace.StartsWith(packageName));

Or instead of searching all types in all assemblies you can search in a single assembly by name

var types = AppDomain.CurrentDomain.GetAssemblies()
    .Single(a => a.GetName().Name == packageName)
    .GetTypes()
    .Where(t => t.IsClass)
    .Where(t => t.Namespace != null)
    .Where(t => t.Namespace.StartsWith(packageName));

The above code assumes the assembly is already loaded.

If you know any type inside the assembly

var types = typeof(SomeKnownType)
    .GetTypes()
    .Where(t => t.IsClass)
    .Where(t => t.Namespace != null)
    .Where(t => t.Namespace.StartsWith(packageName));

The above will ensure the assembly is loaded since you accessed a type in the assembly. Or you can manually load the assembly if it is not already loaded

var types = Assembly.Load(packageName)
    .GetTypes()
    .Where(t => t.IsClass)
    .Where(t => t.Namespace != null)
    .Where(t => t.Namespace.StartsWith(packageName));

Upvotes: 2

Related Questions