Results 1 to 4 of 4

Thread: Placeholder values from an object and/or non app.config

  1. #1
    Join Date
    Sep 2005
    Posts
    6

    Default Placeholder values from an object and/or non app.config

    From the documentation, I can see that Spring supports replacing ${placeholders} with values in specified namevalue sections of [App].config.

    Is there any way for me to instruct Spring to replace placeholders from an instance of an object I provide (I am thinking of something implementing a hypothetical interface called IPlaceholderSource which might or might not exist in reality)? For example, I would like to replace '${machinename}' with the value of Environment.MachineName, and this would need some code to provide the replacement value dynamically.

    I would also like to specify other placeholder values in a file, but not [App].config, so the settings are accessible to all applications in the same directory. If the placeholder values can only be loaded from app.config, I have to duplicate the values in a number of app config files - one for each application in the directory.

    Alternatively, is there a way for me to just define an object in the context which is a namevaluecollection (I can see that setting properties to namevaluecollections is possible), and use some syntax to set properties of other objects to values in this namevaluecollection?

    This is probably incomprehensible - I hope somebody can understand what I'm on about!

  2. #2
    Join Date
    Sep 2004
    Location
    Leeds, UK
    Posts
    166

    Default

    Hiya

    I would also like to specify other placeholder values in a file, but not [App].config, so the settings are accessible to all applications in the same directory. If the placeholder values can only be loaded from app.config, I have to duplicate the values in a number of app config files - one for each application in the directory.
    You can have any number of arbitrary XML files for supplying name-value pairs. See the API documentation for the PropertyPlaceHolderConfigurer class.

    You can supply any old resource location to the 'locations' property of the PropertyPlaceHolderConfigurer class. If your arbitrary name-value pairs are not in your [web]apps .config file, you will have to create a file like this (lets call it dao.config)...

    Code:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    	<configSections>
    		<section name="DaoConfiguration" type="System.Configuration.NameValueSectionHandler, System" />
    	</configSections>
    	<DaoConfiguration>
    		<add key="connection.string" value="dsn=MyDSN;uid=sa;pwd=myPassword;" />
    	</DaoConfiguration>
    </configuration>
    The corresponding .config file would look like this...

    Code:
    <objects xmlns="http&#58;//www.springframework.net" 
    	xmlns&#58;xsi="http&#58;//www.w3.org/2001/XMLSchema-instance" 
    	xsi&#58;schemaLocation="http&#58;//www.springframework.net http&#58;//www.springframework.net/xsd/spring-objects.xsd">
    
            <object name="testObjectDao" type="Spring.Objects.TestObjectDAO, Spring.Core.Tests ">
              <property name="maxResults" value="$&#123;maxResults&#125;"/>
              <property name="dbConnection" ref="myConnection"/
            </object>
        
            <object name="myConnection" type="System.Data.Odbc.OdbcConnection, System.Data"> 
              <property name="connectionstring" value="$&#123;connection.string&#125;"/>
            </object>
            
            <object name="appConfigPropertyHolder" 
                   type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
              <property name="locations">
                <list>              
                   <value>file&#58;//myApp/daoconfig.xml</value>
                </list>
              </property>
              <property name="configSections">          
                <value>DaoConfiguration</value>                              
              </property>
            </object>
    
    </objects>
    If you have the full source codebase, you may wish to check out the unit tests for the relevant classes, which demonstrate how to use this feature. I will amend the reference documentation to include an example of this.

    For example, I would like to replace '${machinename}' with the value of Environment.MachineName, and this would need some code to provide the replacement value dynamically.
    Well, hopefully I'm not going slightly outfield on this response to your question, but environment variable expansion is supported out of the box on the PropertyPlaceHolderConfigurer class. See the API documentation for the above class, and consult the EnvironmentVariableMode property.

    Code:
    Is there any way for me to instruct Spring to replace placeholders from an instance of an object I provide &#40;I am thinking of something implementing a hypothetical interface called IPlaceholderSource which might or might not exist in reality&#41;?
    Good point. I agree that the current implementation (which mandates the use of XML-based name-value pair configuration files) is poor. The class that sources the NameValueCollection should not be coupled to the class that consumes said NameValueCollection... its only done this way to be compliant with the Spring.Java codebase. I don't like this though, and I will change it... a JIRA issue has been pending for some weeks now.

    Ciao
    Rick
    Senior Consultant, Interface21 - Spring Services from the Source

    The Spring Experience - The Premier Spring Event of 2006. December 7-10, 2006, Hollywood, Florida

  3. #3
    Join Date
    Sep 2005
    Posts
    6

    Default thanks

    Thanks Rick - I didnt notice the Location property. After finding a chunk of code for using the placeholder configurer with IObjectFactory, my config file is back from a spring object definition file, to its old self.
    I am not using a placeholder to replace MACHINENAME, because the placeholder in this case is in the 'replacement value' of another placeholder - a SQL connection string. So I'll stick with replacing programmatically in my code for the time being.

  4. #4
    Join Date
    Sep 2004
    Location
    Leeds, UK
    Posts
    166

    Default

    Hiya

    After finding a chunk of code for using the placeholder configurer with IObjectFactory, my config file is back from a spring object definition file, to its old self.
    Cool.

    I am not using a placeholder to replace MACHINENAME, because the placeholder in this case is in the 'replacement value' of another placeholder - a SQL connection string.
    Mmm... well, I'm not trying to be obscene here but perhaps you can take advantage of the fact that the PropertyPlaceHolderConfigurer implements the IOrdered interface to address this issue.

    You could have two PropertyPlaceHolderConfigurers in your context. One of them is pretty much the same one that you have now. The second one (lets call it 'environmentPropertyPlaceHolderConfigurer') is tasked with replacing only environment variables. You make the first configurer (your current one) fire off first by setting its Order property to lets say 0; you then set the same property on the 'environmentPropertyPlaceHolderConfigurer' object to 1. This makes the 'environmentPropertyPlaceHolderConfigurer' object do its property replacing after the first one.

    So then lets say your current properties file contains an entry ...

    <name-values>
    <add key="connectionstring" value="san=Foo;uid=bill;password=ben;server=${MACH INENAME}" />
    </name-values>

    So the first configurer kicks in and replaces all instances of ${connectionstring} with the value 'san=Foo;uid=bill;password=ben;server=${MACHINENAM E}'. The second configurer then gets its chance, and it resolves the placeholder value of '$MACHINENAME}' with well, whatever the value of the MACHINENAME environment variable is on your er, machine.

    Mmm... my explanation seems a bit rough. I'll polish it up (hopefully you get where I'm going), and I'll include an example of this kind of double tap configuration in the reference documentation

    Ciao
    Rick
    Senior Consultant, Interface21 - Spring Services from the Source

    The Spring Experience - The Premier Spring Event of 2006. December 7-10, 2006, Hollywood, Florida

Similar Threads

  1. Possibility to delete DataBindings
    By sir-archimedes in forum Web
    Replies: 7
    Last Post: 05-06-2006, 07:33 AM
  2. Object does not match target type
    By zblock in forum Web
    Replies: 5
    Last Post: 03-23-2006, 01:31 PM
  3. Windows Services and Object in framework 2.0
    By bchebrou in forum Windows Services
    Replies: 5
    Last Post: 01-16-2006, 04:23 PM
  4. Replies: 3
    Last Post: 08-13-2005, 01:25 PM
  5. Child object definitions and abstract classes.
    By Tom Whitner in forum Core Container
    Replies: 5
    Last Post: 12-08-2004, 07:33 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •