0

I have a namespace that defines a class (I'll omit the code):

namespace My.Business.Services
{
    public class ProgressSender
    {
    }
}

This project is saved as a DLL.

In another project in my solution I try to instatiate it in various ways (in reality this is a string in my app.config) but they all fail (it does work explicitly creating the class early bound in code). I've included My.Business.Services as a reference to the program too:

namespace My.Progress.Imaging
{
  static class Program
  {
    static void Main(string[] args)
    {
        string exportItemNS = "My.Business.Services";
        string exportItemC  = "ProgressSender";
        string exportItemFull = "My.Business.Services.ProgressSender";

        //value cannot be null
        ProgressSender obj =     
         (ProgressSender)Activator.CreateInstance(Type.GetType(exportItemFull));

        //could not load type 'ProgressSender' from assembly 'My.Business.Services'
        var obj=Activator.CreateInstance(exportItemNS, exportItemC);

        //could not load type 'ProgressSender' from assembly 'My.Business.Services'
        ProgressSender s=(ProgressSender)Activator.CreateInstance(null, exportItemFull);

       //Loads ok but then classType is null
        Assembly assembly;
        assembly = Assembly.Load(exportItemNS);
        Type classType = assembly.GetType(exportItemC);

   }
 }
}

If I get a type from the same namespace or even System it's fine:

Type t = Type.GetType("My.Progress.Imaging.Program");
t = Type.GetType("System.String");
Neil Walker
  • 6,400
  • 14
  • 57
  • 86

1 Answers1

2

You need to specify the full assembly qualified name. Only for mscorlib and system types can you provide the type name without the assembly name.

So in your case:

"My.Business.Services.ProgressSender, My.Business.Services"

If your type is in a My.Business.Services.dll assembly.

See https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx

Maarten
  • 22,527
  • 3
  • 47
  • 68
  • Beat me by a minute. Yes, need to know (especially if the lib isn't already loaded) the assembly just as much as the type. – Brad Christie Feb 06 '15 at 19:15
  • Thanks. Is it better to use Assembly Load or Activator? This worked, but is there no other way, I'd rather not have to split my string up into namespace and full class name after reading it from xml ProgressSender obj = (ProgressSender)Activator.CreateInstance(exporterItenNS, exportItemFull).Unwrap(); – Neil Walker Feb 06 '15 at 19:26
  • You're already splitting each type to load. If you want to avoid splitting for real, why not save it all as an xml or json, where you can actually have them as separate values with `namespace` and `name` attributes? – SimpleVar Feb 06 '15 at 19:28
  • Thanks, I found a way to avoid string splitting by looping through all the AppDomain items (http://stackoverflow.com/questions/1825147/type-gettypenamespace-a-b-classname-returns-null). Do I need to reference the namespace in my project for Activator to work? Just wondering whether Assembly Load approach is better than Activator? – Neil Walker Feb 06 '15 at 19:36
  • You don't reference namespaces, you reference assemblies or projects. You don't have to reference the assembly but the assembly needs to be 'findable' by the activator to be able to create instances. This means usually that the assembly needs to be copied to the build output folder. Refencing achieves this but there are other ways, for example, a post build event to copy it. – Maarten Feb 07 '15 at 11:31