PDA

View Full Version : Using Spring.NET with non-trivial test-driven applications


Ted Husted
06-20-2005, 04:01 PM
Is anyone else using Spring on a project that

* Deploys web and non-web projects (i.e. unit tests)
* Uses multiple configuration files

The import statement is working well enough for the multiple files, but how can we use the same configuration file, including relative paths, in web and non-web projects?

We setup up a root import file, that includes the others:


<object id="Base" />
<import resource="Resources/Command/AppBase.xml"/>
<import resource="Resources/Command/AppConfig.xml"/>
<import resource="Resources/Command/AppFields.xml"/>
<import resource="Resources/Command/cmdCounty.xml"/>
<import resource="Resources/Command/cmdEvent.xml"/>
<import resource="Resources/Command/cmdFacility.xml"/>
<import resource="Resources/Command/cmdInfraction.xml"/>
<import resource="Resources/Command/cmdLog.xml"/>
<import resource="Resources/Command/cmdMandate.xml"/>
<import resource="Resources/Command/cmdMeetingReport.xml"/>
<import resource="Resources/Command/cmdProgram.xml"/>
<import resource="Resources/Command/cmdRegion.xml"/>
<import resource="Resources/Command/cmdStaff.xml"/>
<import resource="Resources/Command/cmdStatus.xml"/>
<import resource="Resources/Command/cmdStep.xml"/>
<import resource="Resources/Command/cmdTicket.xml"/>
<import resource="Resources/Command/cmdTypes.xml"/>


that we can share verbatim between web and non-web projects, but only if we use a custom singleton to load the non-web projects. The singleton includes some "kludge" code we borrowed from an early version of iBATIS:

private static string _rootDirectory =
AppDomain.CurrentDomain.BaseDirectory.Replace (@"\bin", "").Replace (@"\Debug", "").Replace (@"\Release", "");

This provides us with a consistent root reference that we can prepend to the file:

string foo = "file://" + _rootDirectory + FILE;

For iBATIS, we've since decided that this is too kludgy. Now, the practice is to use runtime properties to set the root for each project. We can then sete the root in one file

root="."

or

root ="../.."

and then maintain a consistent reference in the configuration:

<import resource="${root}/Resources/Command/cmdTypes.xml"/>

Has anyone found another way to accomplish the goal of keeping identical, multiple object configuration files for non-web and web projects?

-Ted.

Rick Evans
06-20-2005, 06:17 PM
Hi Ted

Good post there... I am aware of the issue you have raised, and even filed a JIRA issue concerning it.

The JIRA issue can be found here... it's not quite as exhaustive as your post :D so I will append the relevant portions of your post to the issue.

http://opensource.atlassian.com/projects/spring/browse/SPRNET-86

The other Spring.NET team members are also aware of the issue and we have discussed implementing it in the 1.0 timeframe (btw, we aim to have the 1.0 release out within the month... we're having a big push on that front).

Ted, if you vote for the issue, or if you post again here saying you want it NOW, I will address the issue immediately.

As for your app, shucks, I sure would like to see what is in all those configuration files :D

Ciao
Rick

Ted Husted
06-20-2005, 11:00 PM
Yes, personally, I would find it difficult to call something a 1.0 release unless there is a solution to this configuration issue.

The simplest thing would be to support property files, as several other packages do, like iBATIS and Tiles.

Then you can have a semi-static file for each project that

The parent feature is quite possible, and eliminates many of the other uses for aliases and properties, but I don't see a better solution for the relative-path configuration issue.

-Ted.

Ted Husted
06-20-2005, 11:06 PM
Hi Ted
As for your app, shucks, I sure would like to see what is in all those configuration files :D


The application is based on a chain of responsiblity. All the domain logic is expressed as command or chains of commands, which are injected by Spring.

There are a handlul of base business classes, and then dozens of commands that "decorate" the base classes for a specific use case.

The commands also wrap the iBATIS statements. To include an iBATIS statement in a chain, we can just create a command with the same name as the statement, and the base does the rest.

We also do things like program datagrids through a base class and property injection.

So we end up with an object for every data access statement, and for every business rule, as well as a chain object for when we assemble these into transaction scripts, along with objects that represent data grids.

-Ted.

Mark Pollack
06-21-2005, 07:53 PM
Hi,

Damn, as usual I can't see JIRA from the client site.. :( Anyway, I agree with the need. We could add a <properties> element to the proposed context section. I'll recap that in all its glory here. The properties section would implicitly register a PropertyPlaceHolderConfigurer (http://www.springframework.net/doc/reference/html/objects.html#objects-factory-placeholderconfigurer) so that property replacement could also be performed on object value elements in addition to those contained in the <context> section. We would also have to add support for replacement in the import statements. I'll double check the schema to see if there are any other places where replacement would be appropriate.


<spring>

<context type="Spring.Context.Support.WebApplicationContext, Spring.Web"
objectWrapperType="MyCustomObjectWrapper">

<resourceHandlers>
<handler protocol="db" type="MyCustomDbResource"/>
<handler protocol="dctm" type="MyCustomDocumentumResource"/>
<handler protocol="ldap" type="MyCustomLdapResource"/>
...
</resourceHandlers>

<parsers>
<parser namespace="http://xyz" type="MyCustomXyzConfigParser"/>
...
</parsers>

<properties>
<resource uri="config://MyConfiguration"/>
<resource uri="assembly://MyAssembly/MyNameSpace/MyResourceName"/>

<add key="maxResults" value="1000"/>
<add key="root" value="../.."/>
...
</properties>

<resource uri="${root}/Config/XyzObjects.xml"/>
<resource uri="db://myDataSource/..."/>
<resource uri="dctm://myDocbase/..."/>

</context>

</spring>


How does that look? I'll cross-check again w/ the jira suggestions later.

Cheers,
Mark

Aleks Seovic
06-22-2005, 03:42 PM
I agree with the need as well and in general have no objections to being able to define properties within context definitions, but why did you leave two resource file references within <properties> element?

Mark Pollack
06-22-2005, 04:32 PM
Hi,

I put multiple in order to support more than on property files... Seems reasonable... Thinking about it some more it maybe more appropriate to put <properties> outside the <context> so that other top level elements <aspects>, <services> could also make use of property replacement.

- Mark

Aleks Seovic
06-22-2005, 10:50 PM
I think Rick's proposal for SPRNET-86 makes sense and it should be trivial to implement.

However, as an alternative solution until that's done, why not simply configure VS.Net/NAnt to copy necessary XML files from source tree to build tree? I prefer to have my source files completely separated and never used directly by the application. If you set Build Action property for all those files to "Content" in VS.Net and/or add necessary copy instructions to build files, you will have exact reproduction of the production file&folder layout during testing, which is in my opinion a good thing.

I don't like cludges such as Replace(xyz) that are only necessary in development environment. I'd much rather reproduce production environment by copying necessary files/folders to build directory.

That said, modifying FileSystemResource (and other resources if it makes sense) to treat ~ as a root directory of the application seems like a good idea and should be done.

- Aleks