• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 345
  • Last Modified:

Object Oriented Dilemma

I have a flowchart drawing tool that enables me to draw boxes and the capability to assign an object to each box. In my program, I have a number of functions and subs that perform tasks. And I enable the user to assign these functions to the box.

As an example, in our program we have three functions: copyfile, movefile, and deletefile. Copyfile and movefile have parameters of SourcePathAndName and DestPathAndName, while deletefile only requires a parameter of SourcePathAndName. Each of functions returns a boolean result of success or failure of the copy, move, or delete.

The question is, what is the smart way to design this program so that as I add additional functions (and there will be many more) I can smartly manage the hooks to my "presentation layer" and "execution layer" with the minimum number of steps.

Currently I declare a string array of functions which I load programmatically, replicating the functions I have already created that I want the user to use (in our example, copyfile, movefile, and deletefile). Then at "the other end of the program" where I actually perform the activity (copy, move, or delete the file) I look at the box object and the function assigned to it, do a "select case" based on the assigned function, and call the appropriate function.

My approach works, but whenever a new function (capability) is added, I have to add that function to my "functions array" so my user will be able to see it and assign it to a box. And in my execution routine, I have to add another case statement to call it. It seems like there must be a smarter approach.

I have looked at the programming techniques of reflection and also creating a delegate (to directly execute the function rather than using a series of case statements). Both of these techniques appear promising, but alas I'm not sure if they are applicable to this dilemma.

The best suggestion and sample of how to approach this wins the points. Thank you!
1 Solution
Hi wparrack:
Lets make it easier for us to help you by clarifying your problem.
Could you choose one of the three functions and post snippets of code as to what you have done?
It might make it easier for us to show you how we would approach the same problem


make an interface ...

IApplicationCallableObject {
    ParameterCollection RunFunction(ParameterCollection _Arguments) ;
    ParameterCollection QueryRequiredParameters() ;
    //etc etc
    //maybe add some stuff here to allow custom property dialogs etc i.e.
    Form CustomPropertyDialog { get; };

example class

public class DeleteFile : IApplicationCallableObject {
     ParameterCollection RunFunction(ParameterCollection _Arguments) {
           if(_Arguments == null || _Arguments.Count == 0 || !_Arguments.Contains("Filename") {
                throw new System.Exception("Required Parameter Filename missing") ;
           File.Delete(_Arguments["Filename"]) ;
           return null ;
           //this is actually a sub ... to return you would add values to a parameter collection and return it.

     ParameterCollection QueryRequiredParameters() {
          ParameterCollection ret=new ParameterCollection() ;
          ret.add(new Parameter("Filename", typeof(string)) ;
          return ret ;

in your main code you load them all up into an array or typed collection of IApplicationCallableObjects ... then you just build the parameter array and call ParameterCollection ReturnValues = object.RunFunction(Parameters). This will also allow you to pass multiple values back and forth (or you can just modify the parameter collection given to you to add return values etc) ...

You could very easily make it so that the user tells you to load up say 9 .dlls dynamically (or all in 1 directory etc etc) you then just get all objects that implement this interface and set them as your available objects (You use CreateInstance to do this). The big difference here in comparison with what you are currently doing is that this allows you to add functionality without changing the original code (or even having access to the original code so your end users could actually create their own if they wanted ... just add their own dll to the ones you load :) )

I believe using Relfection is your way to go.  I just wrote a class testing application that required me to use just about everything in System.Reflection.  The classes you will use most often are System.Reflection.MethodInfo, System.Reflection.ParameterInfo, and System.Type  

I see two possible scenarios...

1.)  All your functions are contained in one class

2.)  Your functions are contained in 2 or more classes.

Here are the basic steps you will need to follow...

1.)  Load the assembly that contains your functions.  If they are in your current project solution, they will automatically be loaded.  If they are separate project, you will need to load them at run-time using Assembly.LoadFrom()

2.)  You will then need to list the list of functions using System.Type and its function GetMethods()

3.)  Once the function is selected and parameters values determined, use Activator.CreateInstance to create an instance of the class.  If you want to use something more than the default constructor, ask me and I'll show you how.

4.)  Then create an object array that holds the parameters and use MethodInfo.Invoke to call the actual function.

I used the .Net Framework SDK to learn all this stuff...so that might be a good place to start.  

If you want me to post some code samples to help you along just let me know.
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

why would you loosely type everything through reflections as opposed to just using a strongly typed interface which describes what a plugin can do and just searching for objects which support the interface ?
Why not?  Both ways work.  It depends on what wparrack wishes to do.  I personally would use relfection.  He knows better what he is trying to accomplish and how the requirements may change in the future.  If nothing else, I am giving him another option.
The only time I can see leaving a strongly typed system is if a requirement was set to be abe to call methods of existant framework items etc directly or without wanting to write a wrapper for them.

I say this for a few reasons.

1) You have far less control over the non-strongly typed system (especially when dealing with issues like thread safety)

2) the strongly typed system offers more functionality and higher flexibility for future flexibility i.e. using the strongly typed system you can include custom dialogs for configuration of the plugin or include further information as to what it can do (example: a description of what it can do and a link to a help file)

3) The code is simpler to deal with in the strongly typed method

4) An outside developer is handed a clear contract with the strongly typed method

5) Using the strongly typed method you end up with a very clean result (A directory that contains one or may .dlls which are just loaded at runtime. to add more just drop in more .dlls).

6) You can write a generic loading/metadata system using the strongly typed system that you can reuse for all your future plugin needs (factory and decorator patterns come to mind).

7) This is probably the biggest issue I have with the reflections method: You often times end up in very complex situations configuration wise to do something very simple.

Ex: Lets say I have a singleton object that maintains some values (ill use the example of stock quotes that it refreshes from a server in a seperate thread). I want to call a method which gets will look up my quote and return the price. I now need to support the ability to call the member which returns the instance and then goes and calls the instance member of this ... Its very easy to call a single function using reflections but allowing you to define and string together multiple calls becomes much more difficult. There is the easy solution of writing a wrapper function which does this but I have already discussed not having to write a wrapper as being one of the reflection methods largest advantages.

Given all of this I will finally point out that this is how Microsoft does it in .net --- IComponent

You bring up some very good points and I agree with you.  The strongly typed system would be a better fit in this situation.  You seem to have a more in depth understanding of .Net than I do yet.  Thanks for the full, clear explanations.  
wparrackAuthor Commented:
Thank you to all who responded. gregoryyoung gets the points, as it directly addresses my problem (and I even understand the solution! (smile)). And it opens the door to managing 3rd party dll's which I would also like to do. You guys are good!!!
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now