Solved

Object Oriented Dilemma

Posted on 2004-04-24
8
316 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
 
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

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…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

757 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now