To start, I'll discuss why you might want to do this. One of the most common reasons I've found is in a modular application where you include different modules into one larger application. When you do this things like installers or the menu system needs to be set-up for each module. In this example we'll look at providing a dynamic menu system.
Menu Classes
Our menu is not going to be fully featured, it actually won't do anything but provide categories and options. We're going to create the following simple classesMenuCategory.java public class MenuCategory { private String name; ... Accessors and Equals and HashCode Here... } MenuOption.java public class MenuOption { private MenuCategory category; private String name; ... Accessors and Equals and HashCode Here... }We'll also create a Menu class that we can add all of our Options. Adding them to this class will push them into a map that uses the category as the key. You'll also notice the @Alternative qualifier. This is so that when we inject the Menu later the CDI container won't be confused.
Menu.java @Alternative public class Menu { private Map<MenuCategory, List<MenuOption>> menuOptions; public Menu(){ menuOptions = new HashMap<MenuCategory, List>(10); } public void addOption(MenuOption option){ if(!menuOptions.containsKey(option.getCategory())){ menuOptions.put(option.getCategory(), new ArrayList ()); } menuOptions.get(option.getCategory()).add(option); } public Map<MenuCategory, List<MenuOption>> getMenuOptions() { return menuOptions; } }
Menu Option Provider and Menu Producer
Next we need a common way to provide the Menu Options, and we have an interface to the rescue.public interface MenuOptionProvider { List<MenuOption> getMenuOptions(); }And now we can start the fun with instances, first we'll start by making our class
public class MenuProducer { ... }And next we'll inject our Instance interface.
@Inject @Any InstanceNow that we have our Instance, instead of limiting it with a qualifier, like we did in the last post, we're going to use all Instances it can find. So, instead of using the select and get methods, we're going to take advantage of the fact that it is Iterable.optionProviders;
@Produces public Menu produceMenu(){ Menu menu = new Menu(); for(MenuOptionProvider provider:optionProviders){ for(MenuOption option:provider.getMenuOptions()){ menu.addOption(option); } } return menu; } }And that's it, we now have our dynamic menu, if you want to see it at work implement the MenuProvider like this:
public class FileMenu implements MenuOptionProvider { @Override public ListDownload the source of this example here.getMenuOptions() { MenuCategory category = new MenuCategory(); category.setName("File"); List options = new ArrayList (); String[] optionNames = {"Open", "Save", "Close"}; for (String optionName : optionNames) { MenuOption option = new MenuOption(); option.setCategory(category); option.setName(optionName); options.add(option); } return options; } }
And that concludes our example today. I hope you've enjoyed this post and that it has helped you in some way.
No comments:
Post a Comment