0

Does anybody know of an easy way to create an instance of a class given the FullName of a type (namespace.classname format), but not having the AssemblyQualifiedName? The FullName of the type is only contained in a single assembly that is referenced and available at runtime, so there is no ambiguity.

I don't have the type, I have a string - the fullname only, without the assembly part. I don't know the assembly, I just know it's referenced and there is only one assembly containing the type fullname.

Thanks!

EDIT: This is to do with deserialization of instances from a proprietary protocol. I've recieved good answers, but what I'll end up do in order to have optimal solution and not iterate through all the assemblies is to create a static dictionary with fullName key and assembly qualified name as value, given I know which exactly are the classes and they are a limited set.

vezenkov
  • 4,009
  • 1
  • 26
  • 27
  • If you can get the `Assembly` object (perhaps via `typeof(SomeKnownType).Assembly`), you can use `thatAssembly.GetType(fullName)` ? – Marc Gravell May 14 '19 at 15:59
  • @ Marc Gravell no, I don't have the type, I have a string - the fullname only, without the assembly part. I don't know the assembly, I just know it's referenced and there is only one assembly containing the type fullname. – vezenkov May 14 '19 at 16:02
  • 1
    If your assembly is already referenced in your project, you don't need the Assembly Qualified Name. – Robert Harvey May 14 '19 at 16:04
  • in the comment above, I only used the `fullName`. The `SomeKnownType` was just **any other type** from that assembly, as a lazy mechanism of getting the `Assembly` instance – Marc Gravell May 14 '19 at 16:04
  • Have you take a look on [AssemblyResolve event](https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.assemblyresolve?view=netframework-4.8) to resolve the missing assembly name? – Troopers May 14 '19 at 16:10
  • @ Robert Harvey I don't know the assembly - might be few of the assemblies - I get only the fullName of the type from the protocol. So the only option is to iterate through the assemblies or define a static dictionary and use it at runtime to find the assembly. If you know a more convenient way, please post it as an answer, I'll accept it. – vezenkov May 14 '19 at 21:16

2 Answers2

3

You can get all of the active assemblies and then look through each one for a type with the full name you have. You'll need to prepare for the possibility that there are multiple matches, or no matches, among the assemblies.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • This is what I am trying to avoid doing. It's to do with several assemblies and types that are referenced for sure (proprietary) where these are being deserialized and recreated as instances. What I am thinking as an alternative is to create a static dictionary with fullName key and assembly qualified name as value. – vezenkov May 14 '19 at 20:59
0

Load all of your assemblies and select over their types, then filter on the name.

public static object CreateType(string typeName)
{
    var allTypes = AppDomain.CurrentDomain
        .GetAssemblies()
        .SelectMany
        (
            a => a.GetTypes()
        );
    var type = allTypes.Single( t => t.Name == typeName );

    return Activator.CreateInstance(type);
}

You might consider adding some validation code to check for duplicates, and to ensure there is a default constructor.

John Wu
  • 50,556
  • 8
  • 44
  • 80
  • Good - it's a way to do it and I mark it as an answer (provided the code), maybe slow if many assemblies and types, but that's it. I'd check for "&& t.IsClass && !t.IsInterface && !t.IsAbstract" to be sure CreateInstance will work - although in my particular case it will work without this check. – vezenkov May 14 '19 at 21:29