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
Solved

Object Oriented Dilemma

Posted on 2004-04-24
8
333 Views
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!
0
Comment
Question by:wparrack
8 Comments
 
LVL 27

Expert Comment

by:Dabas
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

Dabas
0
 
LVL 37

Accepted Solution

by:
gregoryyoung earned 500 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 :) )

Greg
0
 
LVL 1

Expert Comment

by:warmach
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.
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 37

Expert Comment

by:gregoryyoung
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 ?
0
 
LVL 1

Expert Comment

by:warmach
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.
0
 
LVL 37

Expert Comment

by:gregoryyoung
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

0
 
LVL 1

Expert Comment

by:warmach
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.  
0
 

Author Comment

by:wparrack
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!!!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone 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

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

808 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