15

In my code I am trying to get a type by name. When I was using a string argument I failed. Then I have tried to do the follwing in the Quick watch window:

Type.GetType(typeof(System.ServiceModel.NetNamedPipeBinding).Name)

returns null. Why? and how to get the desired type by name?

Yaugen Vlasau
  • 2,148
  • 1
  • 17
  • 38

5 Answers5

13

If you want use simple name (not AssemblyQualifiedName), and don't worry about ambiguous, you can try something like this:

    public static Type ByName(string name)
    {
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies().Reverse())
        {
            var tt = assembly.GetType(name);
            if (tt != null)
            {
                return tt;
            }
        }

        return null;
    }

Reverse() - for load most recently loaded type (for example after compilation of code from aspx)

Vladimir
  • 2,082
  • 1
  • 13
  • 27
7

Type.GetType can only find types in mscorlib or current assembly when you pass namespace qualified name. To make it work you need "AssemblyQualifiedName".

The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.

Referece Type.GetType

System.ServiceModel.NetNamedPipeBinding lives in "System.ServiceModel.dll" hence Type.GetType can't find it.

This will work

Type.GetType(typeof(System.ServiceModel.NetNamedPipeBinding).AssemblyQualifiedName)

Or if you know the assembly already use following code

assemblyOfThatType.GetType(fullName);//This just need namespace.TypeName
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • you are right. thanks! can you give me any ideas about getting to AssemblyQualifiedName from the type name? or how can I get an instnace of NetNamedPipeBinding by name "NetNamedPipeBinding". Initial idea was Activator.CreateInstance(myType); where my type was a correct type – Yaugen Vlasau Nov 15 '13 at 19:08
  • Atleast do you know which assembly type lives in? – Sriram Sakthivel Nov 15 '13 at 19:11
  • Check my update if that helps.. to get assembly instance use typeof(AnyTypeFromServiceModelAssembly).Assembly – Sriram Sakthivel Nov 15 '13 at 19:14
  • I wish they will make it more clear what are the consequences of doing this one, as it will not try to load it from your app domain, but instead will try to read it directly from the dll. – HellBaby Aug 03 '22 at 19:35
2

Based on Vladimir's answer here is a LINQ version with the optional part of falling back to the first partial result if no exact match found:

private static Type ByName(string name)
{
    return
        AppDomain.CurrentDomain.GetAssemblies()
            .Reverse()
            .Select(assembly => assembly.GetType(name))
            .FirstOrDefault(t => t != null)
        // Safely delete the following part
        // if you do not want fall back to first partial result
        ??
        AppDomain.CurrentDomain.GetAssemblies()
            .Reverse()
            .SelectMany(assembly => assembly.GetTypes())
            .FirstOrDefault(t => t.Name.Contains(name));
}
g.pickardou
  • 32,346
  • 36
  • 123
  • 268
  • This is cool. I just modified this method by putting it in a static By class. The code looks pretty then, By.Name("IWhatEverService"); Thanks! I needed this for targeting a dependency registered from another project I couldn't reference. – michael g Dec 08 '22 at 04:11
0

.Name gives you NetNamedPipeBinding, for GetType to work you'll need full assembly name (AssemblyQualifiedName)

Konstantin
  • 3,254
  • 15
  • 20
0

The other answers almost have it right. To load a type by name, you either need it's full name (if the assembly has already been loaded into the appdomain) or its Assembly Qualified name.

The full name is the type's name, including the namespace. You can get that by calling Type.GetType(typeof(System.ServiceModel.NetNamedPipeBinding).FullName). In your contrived example, this will work (since NetNamedPipeBinding's assembly is assured to be loaded).

If you can't be sure it's loaded, use Sriram's answer, and pass a full assembly qualified name (TopNamespace.SubNameSpace.ContainingClass, MyAssembly). This will have .NET try to find and load htat assembly, then get the type.

Avner Shahar-Kashtan
  • 14,492
  • 3
  • 37
  • 63