How can I detect the presense of an optional assembly and call a method within it?

  • Thread starter Thread starter Gaetan
  • Start date Start date
G

Gaetan

I would like to extend the capabilities of my application by calling a user method
residing in a client provided assembly without having to recompile my application.

Things would work like this:

1- Read a configuration file where the client provides the assembly name (DLL) and the
method name.

2- Detect the existence of the assembly file.

3- Invoke the client method.

I'm not sure how to handle item #3. I cannot add a reference to the client DLL in my
application since I do not know in advance what the assembly name will be nor the method
name. Can someone provide me a clue on how I should handle it?

Thanks.
 
The client can configure his assembly and provide information about it in a
client.config file but this happens with .Net Remoting. If this is not what
you are looking for, please tell me what is your client.

Regards,

Jv
 
You need more than just the assembly name, you also need the class name that
will be invoked against.

Basically you will need to use Reflection. The idea being that reflection
allows you to dynamically create instances at runtime and invoke method.
Take a look at reflection and see if this helps.
 
Here is how you can go about it.
The config file should have the following details for each method that
needs to be invoked - The assembly, the type and the method name.

First you need to create an instance of the object on which the method
call will be invoked. Use the static CreateInstance method of the
Activator class that accepts the assembly name and the type name as
arguments

object dynamicObj=Activator.CreateInstance(assemblyName,
typeName).Unwrap();

If the assembly doesn't exist or an incorrect typName is specified,
then the above statement will throw a FileNotFound Exception or a
TypeLoad Exception respectively, which you can catch and process
accordingly. The typeName should be specified as namespaceName.typeName
where namespaceName is the namespace under which typeName is defined.
Once, you have a "live" object, you can use methods of the Type Class
and the MethodInfo class to invoke the specified method.

Type dynamicType=dynamicObj.GetType();
MethodInfo dynamicMethod=dynamicType.GetMethod(methodName);

I'm assuming that the method to be invoked is not overloaded. If that
is not the case, then you need to use an appropriate overload of the
Type.GetMethod method, specifying the input parameter types.

object returnValue=dynamicMethod.Invoke(dynamicObject, null);

Again, assuming that the method to be invoked does not accept any
parameters. You can find more detailed explanations and examples in the
msdn documentation for Type and MethoInfo classes.

Hope this helps.
Regards,
Sarin.
 
This useful information seems to be what I was looking for. Now reading more about
Reflection and the methods you indicated.

Thank you.
 
Hello Gaetan!

Well this might not be the perfect Plugin approach (i.e. have a static
reference to client assembly) but just an idea, may be you feel worth
implementing. Its based on the use of config file and reflection.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ClientSection"
type="System.Configuration.DictionarySectionHandler" />
</configSections>
<!-- Custom Section -->
<ClientSection>
<add key="BusinessAssembly" value="<your_assembly>" />
<add key="BusinessType" value="<your_type>" />
<add key="BusinessMethod" value="<your_method>" />
</ClientSection>
<!-- / Custom Section -->
</configuration>


public Object DoAction()
{
try
{
Hashtable configData = (Hashtable)
ConfigurationSettings.GetConfig("ClientSection");
if(configData==null) throw new ArgumentNullException("Unable to read
configuration section");
// Get Assembly
String strAssembly =
Convert.ToString(configData["BusinessAssembly"]);
Assembly assembly = Assembly.Load(strAssembly);
if(assembly==null) throw new Exception("Unable to load assembly:
"+assemblyName);
// Get Type
String strType = Convert.ToString(configData["BusinessType"]);
Type workingType = assembly.GetType(strType);
if(workingType==null) throw new Exception("Unable to load type:
"+workingType);
// Get Method
String strMethod = Convert.ToString(configData["BusinessMethod"]);
MethodInfo methodInfo = workingType.GetMethod(strMethod);
if(methodInfo==null) throw new Exception(strAssembly+" (type:
"+workingType+") doesnot contain "+strMethod);
// Type Instance
Object obj = assembly.CreateInstance(strType, true);
if(obj==null) throw new Exception("Instantiation failed for
"+strType);
// Invoke Method
Object objReturnValue = methodInfo.Invoke(obj, null);
return objReturnValue;
}
catch(Exception ex) { throw ex; }
}


Its just a thought, I hope this might be of some help. I cant predict
the correctness of the code since i wrote it in "wordpad" [i have a
problem with my VS.NET] :-)

Let me know in case of any inconsistancy.

Regards,

Moiz Uddin Shaikh
Software Engineer
Kalsoft (Pvt) Ltd
 
Hello Again!

Just to make a typo correction in the first paragraph.

"Well this might not be the perfect Plugin approach (i.e. DONT have a
static
reference to client assembly) ..."

Plugin Approach is based on the idea that you DONT have a static
reference to an assembly and the fuctionality of the assembly is
exploited at runtime.

Regards,

Moiz Uddin Shaikh
Software Engineer
Kalsoft (Pvt) Ltd
 
Thanks Moiz for the sample code. I already have XML support in my appl. However your code
to load and invoke an external method will surely be reused shortly.

Gaetan.
 
Back
Top