views:

37

answers:

3

I have the full path to a dll, but not a reference, where I need to instantiate an object that implements an interface that I've defined. I do have control over the other dll, so I am able to do things like stick a static function in the dll that returns the object I need. I'm just not sure how to call that function, or even if I'm approaching this right.

+2  A: 

You'll need to manually load the assembly, then use reflection to find and execute the method you're interested in. Here's an article.

The interesting calls/statements in that article are:

  • Calling Assembly.Load() to have the runtime load the assembly into the AppDomain (making it's members callable).

  • Searching the Types contained in the assembly

  • Building MethodInfo and ConstructorInfo objects, which are the reflection components used to call a method or instantiate an instance, respectively

  • Calling .Invoke() on the MethodInfo or ConstructorInfo. Invoke() is essentially telling Reflection to execute the corresponding method.

STW
+1  A: 

You can load the assemby at run time and you System.Activator or reflection to instantiate a type in that assembly. If the type you are looking to get an instance of does not have a default constructor, you will have to pass it the correct parameters. This can be the tricky bit, but if the types are easy to construct (in the same method) this is simple too. If you are calling a method that constructs this type, it will return an object if successful. I suspect the interface that you are referring to is not strictly a .Net interface, rather a set of public methods for accessing the type. You can use reflection to invoke these also.

MaLio
A: 

Here's a snippet of code that I use, with the company specific stuff stripped out. Once you've loaded the assembly (I can't remember off the top of my head if this code loads the assembly for you or not), this works a treat.

public static IMyType GetInstanceOfMyType()
{
    var myTypeDescriptor = "My.Fully.NameSpaced.TypeName, My.Assembly.Name, Version=1.0.0.0, Culture=neutral"

    IMyType _instance = null;

    try
    {

    var myType = Type.GetType(myTypeDescriptor, true, true);
    if (inst.GetInterface("IMyType") != null)
    {
        // For a constructor that takes a single parameter, that's a string
        var constructorInfo = myType.GetConstructor(new Type[] { typeof(string) });
        _instance = (IMyType)constructorInfo.Invoke(new object[] { "String to Pass To Constructor" });

    }
    else
    {
        // Type isn't correct, complain here.
    }
    }
    catch (Exception ex)
    {
       // Log any errors here
    }

    return _instance;
}

The "any errors" are usually one of:

  • The type that you've named in myTypeDescriptor does not exist
  • The type that you've named in myTypeDescriptor doesn't implement IMyType
  • The type that you've named in myTypeDescriptor doesn't have a constructor that matches that which you've specified in the call to GetConstructor
  • The constructor threw an exception; if so, it can be found in ex.InnerException
Rob
Apologies for it being in VB.net, you'll probably have little trouble changing it to VB.net as it's not doing anything particularly arcane =)
Rob
No problems, I generally prefer C#. This project just happens to be in VB.
JupiterP5