1
votes

I am working on a configuration issue with spring, related to using a component based architecture, and how spring loads it's configuration files.

The problem is that each component will add information to the spring context, but in order to load a new config from the assembly, you have to edit the web.config and add in the config resources for that component (or at the very least edit an existing resource file and import the component's config from the assembly). The web.config is "owned" by another group, and cannot be edited.

What I would like is the following:

(1) create a specific directory in the App_Config for my spring files

(2) add a filewatcher to that directory to reload the application if an XML file is added / removed from the folder (Sitecore does this already)

(3) If I deploy a component (call it xyz), I would deploy an xyz.spring.xml file to the folder, which would include a single import statement for the proper configs within the assembly such as : <import resource="assembly://PageTypes.Service/PageTypes.Service/PageTypes.xml"/> or if I needed a config for test / debug configuration <import resource="assembly://PageTypes.Service/PageTypes.Service/PageTypes.DEBUG.xml"/>

(4) Add some code to tell spring (I am guessing a specialized implementation of the WebApplicationContext), that loads all files within a folder and processes them as config resources. Where we currently have

<resource uri="~/App_Config/xyz.xml" />

I would like something like

<resourceFolder path="~/App_Config/Spring" />

Anyone know how to do this, or if something similar exists already I can view?

... I am also open to other suggestions that get me what I want ...

1
Ok, no takers? Let's simplify this a bit - just the second part, how do I get spring to load all of the configs from a directory in a web context? - Brian Beckham

1 Answers

0
votes

Ok, so I think I have an answer for this....

Since I am using this "plugin" style architecture, I needed spring to load all config files from a given folder (which I watch for changes in order to reload the application context). The filewatcher element was already available in the CMS I am using (thanks Sitecore), so I only had to work on a way to load the configs.

So, what I did was to create an implementation of IResource that allows me to use a custom protocol to load spring resources.

Step 1 - web.config changes

First I create resourceHandler section:

<sectionGroup name="spring">
   <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
   <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
   <section name="resourceHandlers" type="Spring.Context.Support.ResourceHandlersSectionHandler, Spring.Core"/>
</sectionGroup>

Then I add code for my custom resource handler

<spring>
   <resourceHandlers>
      <handler protocol="dir" type="TI.Base.Spring.DirResourceHandler, TI.Base"/>
   </resourceHandlers>
<context>
   <resource uri="dir://~/App_Config/Spring" />
</context>
</spring>

Next, I created the DirResourceHandler - which very closely models StringResource provided by Spring - the meat of this is in the initialization:

/// <summary>
/// Load all of the resource files in the directory, and create a virtual file importing all of those files
/// </summary>
/// <param name="resourceName"></param>
private void Initialize(string resourceName)
{
    string resourceNameWithoutProtocol = GetResourceNameWithoutProtocol(resourceName).TrimEnd(new [] {'/'});

    Path = HttpContext.Current.Server.MapPath(resourceNameWithoutProtocol);
    DirectoryInfo = new DirectoryInfo(Path);

    IEnumerable<FileInfo> files = DirectoryInfo.EnumerateFiles("*.xml");
    StringBuilder sb = new StringBuilder();

    sb.Append("<objects>");

    foreach (FileInfo xmlFile in files)
    {
        sb.Append(string.Format("<import resource=\"file://{0}/{1}\"/>", resourceNameWithoutProtocol, xmlFile.Name));
    }
    sb.Append("</objects>");

    Contents = sb.ToString();
}

Can any of you Spring gurus evaluation this solution and tell me if it's viable?