2

I have a TreeView and I want to enable the context menu when clicking with the right mouse button. It is composed by items from different classes, but they all share the same base class.

So, I was considering to create a FactoryClass for each different item class that simply returns a custom IContextMenu interface (that later will be used by some other part of program to actually render the menu).

This is the current workflow I have in mind

  1. The TreeView intercept the right click and request to another class (let's call it ContextMenuFactory) to create a Context menu for that item type
  2. ContextMenuFactory redirect to a specific factory class associated to the input item type (like IFooItemContextMenuFactory)
  3. IFooItemContextMenuFactory class actually create the IContextMenu instance

What makes difficult this task is the second step.

I don't know how can I organize my code in order to make it dynamic because the only solution I have in mind it's just to implement a switch and create the factory class after I have recognized the type.

The ideal way would be to use the container to find the configured implementation, in this way I don't have to modify every time I create a new item type the switch previously suggested.

5
  • 1
    the only solution I have in mind it's just to implement a switch and create the factory class after I have recognized the type -- That's how it is done. How else are you going to know which object to create? Apr 7, 2015 at 12:49
  • It's quite a problem because I would like to be able to load even types that I don't know. I'm implementing MEF to discover dynamically the implementation so someone could extend the application if he provides both the new item type and the related Factory class.
    – simoneL
    Apr 7, 2015 at 12:52
  • Could it be discovered via reflection, perhaps? Also, configuring types via their name in some configuration file like an XML file is not all that difficult. You instantiate them by name with Activator.CreateInstance() (in C#) Apr 7, 2015 at 12:53
  • Maybe, I don't know. Anyway I'm more interested to speak about the theoretical side of this problem. It's not the first time that I have the same kind of issue (find an implementation based on a input parameter) and I still have a lot of doubts about the right way to resolve it. Some real world example would be really appreciated
    – simoneL
    Apr 7, 2015 at 12:55
  • Do you know accepting answers improves your reputation and let other users know what solution helped you the most? Apr 9, 2015 at 14:42

1 Answer 1

3

I would do this:

  • For every class that implements IContextMenu create a Factory/Creator. For example for a class named TypeAContextMenu create a TypeAContextMenuCreator, for TypeBContextMenu create a TypeBContextMenuCreator, etc. Every creator implements the same interface, like say IContextMenuCreator, they just have a create() method that returns an object of type IContextMenu;
  • Create a HashMap, instantiate all creators and put them in the HashMap with a tag:

    Map<String,IContextMenuCreator> c = new HashMap<String,IContextMenuCreator>();
    creator.put("TYPEA", new TypeAContextMenuCreator());
    creator.put("TYPEB", new TypeBContextMenuCreator());
    creator.put("TYPEC", new TypeCContextMenuCreator());
    
  • Then the object you right-click on in the tree view should include the tag of its corresponding IContextMenuCreator as a member.

  • When you right-click, get the appropriate creator from the HashMap. No need for switches. When new types of contextual menus are created you only have to add them in one place.

    IContextMenu cm = creators.get(tag).create();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.