Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


Object Oriented Dilemma

Posted on 2004-04-24
Medium Priority
Last Modified: 2010-04-24
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!
Question by:wparrack
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 27

Expert Comment

ID: 10913686
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

LVL 37

Accepted Solution

gregoryyoung earned 2000 total points
ID: 10914127

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 :) )


Expert Comment

ID: 10918118
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.
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 37

Expert Comment

ID: 10918234
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 ?

Expert Comment

ID: 10918390
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.
LVL 37

Expert Comment

ID: 10919801
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


Expert Comment

ID: 10920324
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.  

Author Comment

ID: 10924485
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!!!

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Well, all of us have seen the multiple EXCEL.EXE's in task manager that won't die even if you call the .close, .dispose methods. Try this method to kill any excels in memory. You can copy the kill function to create a check function and replace the …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question