In the past, I have always utilized an xml file that would contain all of the configuration information for an application … things like data sources, paths, etc. Then, in the application.cfm/cfc file, I would read that xml file, parse it into a structure and store that structure in the application scope. Recently however, I came across an application that was originally designed using a series “config” beans. The application was pretty rough and I was doing a lot of refactoring, so I just inserted my usual xml config file, commented out the beans and moved on without really considering the potential benefits.
Since then, I have seen some discussions about configuration data and done some more reading and I am changing my opinion of configuration beans. As an example, take a basic data access object (DAO). If this DAO communicates with a database of some variety, you will probably need a data source name and possibly a username and password. Now with my config file approach, I would just reference application.config.dsn as a variable in the data access object. The problem with this is that the data source object is now dependent upon the application scope and a variable whose existence and content was not under the control of the object … not a good idea.
Enter the configuration bean. As a very simplistic definition, a bean is simply an object that holds data and should have getters and setters to encapsulate that data properly. So, we could have a data source bean that has three properties … a data source name, a user name, and a password. Then, in the init method for our data access object, we setup a configuration argument which accepts this configuration bean and stores it in the instance ‘scope’ for the data access object. Now instead of referencing application.config.dsn to find the data source name, we simply look at variables.instance.config.getDSN(). We have simplified the inheritance and replaced one dependency with another better one.
The only complex part of this is that we have to declare an instance of the data source config bean, populate it, and then pass it to the data access object. This is where dependency injection and ColdSpring help out. In our ColdSpring beans file we could make an entry for the data source config bean and pass either the path to an xml file that contains the data source settings or we could put the settings direction in the ColdSpring xml to be injected into the data source config bean. Then, we make an entry in the ColdSpring beans file for the data access object and simply provide the data source config bean as a parameter to be injected. Now, when we create a new instance of the data access object, it will already be pre-loaded with the data source configuration information and have no dependency on the application scope or other external variables.
Just as a side note to answer one question that came to my mind … we could easily have had ColdSpring directly inject the data source name, username, and password into the data access object. Having that information stored in a bean gives a bit more flexibility in being able to make changes to it programmatically through the application. Is this enough justification for instantiating another object (even if that object is a singleton) … maybe, maybe not. It is one of those questions there is not a right or wrong answer to.
This concludes our light bulb, eureka moment for today.