Results 1 to 4 of 4

Thread: How to express a common factory idiom using Spring

  1. #1
    Join Date
    Jun 2005
    Posts
    3

    Default How to express a common factory idiom using Spring

    Greetings:

    I'm enjoying my eperiments with spring, and have a question about how to incoporate an existing factory idiom I use in in some current apps.

    I have factories that load many flavors of an object (for example to represent a plugin for a particular media type). I load them up from a configuration file and put the objects on a hashtable.

    Each media type has additional info that is associated with it, besides the plugin. This is currently loaded into a bunch of helper objects accessible through another factory. All of it encoded in an XML file:

    Code:
    <ArrayOfAnyType xmlns&#58;xsd="http&#58;//www.w3.org/2001/XMLSchema" xmlns&#58;xsi="http&#58;//www.w3.org/2001/XMLSchema-instance">
      <anyType xsi&#58;type="LibraryItemHelper">
        <HasChildren>false</HasChildren>
        <VisibleInUI>true</VisibleInUI>
        <Id>ppt</Id>
        <Description>Powerpoint Presentation</Description>
    <PluginClass>MostMedia.Cwrapper.Plugins.PowerPointPlugin,CorePlugins.dll</PluginClass>
      </anyType>
    .
    .
    .
    </ArrayOfAnyType>
    Curently, I'm loading both factories into the IApplicationContext in order to inject their dependencies and to take advantage of the quasi singleton pattern you offer.

    However, in doing so the objects created by my factories aren't managed by Spring and so can't take advantage of features like the loosely bound event publishing mechanism. I could of course eliminate my factory and load each flavor of plugin and its helper object into the IApplicationContext and retrieve from there. But it seems that this is less elegant than my first approach since I'll have to have an entry for every single plugin and helper object in the spring configuration

    Code:
                <object name="PowerPointPlugin" type="MostMedia.Cwrapper.Plugins.PowerPointPlugin,CorePlugins.dll">
                    <constructor-arg  index="0">
                          <ref object="libraryFacade"/>
                    </constructor-arg>
                    <constructor-arg  index="1">
                          <ref object="powerPointFacade"/>
                    </constructor-arg>
                </object>
     <object name="PowerPointPlugin" type="MostMedia.Cwrapper.Core.LibraryItemHelper,CwrapperCore.dll">
     <property name="HasChildren">false</property>
     <property name="VisibleInUI">true</property>
    <property name="Id">ppt</property>
    <property name="Description">Powerpoint Presentation</property>
     </object>
    Say I have 8 media types, it seems much less elegant to have 16 entries that follow the above pattern, then to have my factory instantiate the objects using reflection and inject all the necessary dependencies:

    Code:
    		if &#40;!myContents.ContainsKey&#40;item.ItemType&#41;&#41;
    			&#123;
    				string &#91;&#93; pluginInfo =Utilities.splitString&#40;",",myHelper.PluginClass&#41;;
    				if &#40;pluginInfo.Length != 2&#41; throw new ConfigurationException&#40;item.ItemType + 
    												" PluginClass property requires a class and assembly name seperated by a comma"&#41;;
    				
    				ObjectHandle hdl = System.Activator.CreateInstanceFrom&#40;pluginInfo&#91;1&#93;.Trim&#40;&#41;,pluginInfo&#91;0&#93;.Trim&#40;&#41;&#41;;
    				ICwrapperPlugin aPlugin = &#40;ICwrapperPlugin&#41;hdl.Unwrap&#40;&#41;;
    				aPlugin.Ppt = myPptFacade;
    				myContents.Add&#40;item.ItemType,aPlugin&#41;;
    		
    
    			&#125;
    return  &#40;ICwrapperPlugin&#41; myContents&#91;item.ItemType&#93;;

    This IApplicationContext approach seems to have a number of other disadvantages. The info about a media type is now in two places in the spring config file instead of one place in mine. I'll need to provide a facade that can tanslate my media type id to the correct spring id (since I can't assign the same id to both the media object helper and the media object pluging e.g, "ppt"). Finally seems to me that I lose information on how my app hangs together, about dependencies that really matter.

    I'm guessing that if my objects aren't managed by the spring framework, I won't be able to take advantage of things link AOP. Do I need to implement my own IFactoryObject. If I do will this play nicely with the objects in the IApplicationContext . For example can they use the messaging feature and AOP features?




    Thanks,
    _______________
    Robert Moskal
    Most Media
    Brooklyn, USA

  2. #2
    Mark Pollack is offline Spring.NET Co-Lead Spring TeamSpring User
    Join Date
    Sep 2004
    Location
    New York, NY
    Posts
    1,683

    Default

    Hi Robert,

    First off, thanks for trying out Spring.NET. I'll try to take each point in turn. The approach you are using currently is a good first step - namely loading your existing factories into the application context. You are also correct in that the current plug-in class declared in the config file processed by your factory is not visible to Spring and this does have some implications. The most important of which is not being able to have IObjectPostProcessors or IObjectFactoryPostProcessor automatically applied to created objects. This would apply to AOP functionality, though nothing would prevent you from creating an AOP proxy in code yourself. Similarly, you can still take advantage of the EventRegistry to publish and subscribe to events by getting a reference to the application context and calling its publish or subscribe methods. The object being registered need not be created by Spring to interact with the EventRegistry. In fact this functionality isn't yet exposed via the XML configuration - I recently posted to the dev list a suggestion on how to do this.

    Moving on to eliminating the use of your factory classes, one thing that caught my attention at the design level was that information associated with the media type - the plugin and the helper information were not explicitly captured in the domain model. It seems the relationships are loosely associated by having the same key name in separate factories/lookup tables. Is that right? I think it may be beneficial to create one object, call it MediaType, that has explicit Plugin (ICwrapperPlugin) and MediaTypeHelper associations accessible via properties. Maybe even shift the helper properties up into the top level class MediaType.

    It is true that your current dedicated factory classes and associated configuration files are more terse than Spring's, but they are not as powerful or generally applicable to your application as a whole. So while you may gain in some respects - I think the benefits of getting Spring's object factory features is worth the verbosity. Not to mention avoiding the need to write infrastructure code in the first place. As a side note we are going to address the verbosity in the configuration file in two ways. First by supporting values and refs as attributes instead of elements and second by allowing for custom xml parsers to be registered. Once that is done you could probably have the same XML as you do now but adding a namespace prefix.

    It seems to me that the fact that you need to list one object for the plugin and one for the helper class using Spring is a reflection that the current design doesn't have an explicit dependency between these two classes. The fact that your configuration file puts this information close together is just masking the fact that the objects are in fact not directly associated with each other in the oo-model. I could be off base here so let know.

    That being said, even if you use a new class that is a composite of the plugin and MediaTypeHelper, you could end up having two entries anyway - but there would be an explicit reference between them in the configuration file making it easy to see the dependencies. You may want to look into using inline object definitions. This would allow you to group all the required information within one xml object element.

    Ok, long post, let me know what you think.

    Cheers,
    Mark

  3. #3
    Join Date
    Jun 2005
    Posts
    3

    Default

    Mark:

    Thanks for the quick thoughtful reply.

    You're absolutely right, making each plugin a member of the corresponding LibraryItemHelper class would indeed solve all the problems I mentioned. I' d then just use spring to inject the plugin class into the helper.

    I only hesitate a little about this approach in that I had been using the LibraryItemHelper as a source for configuration information and business rules. Each of the application components would take what it needed from this object. The Plugin factory would grab the plugin info. The Client that displayed and or manipulated the items would use some of the other properties, like whether it can have children or is visible in the UI.

    So I guess my hestitation lies in making the LibraryItemHelper into a kind of super object, one that knows and does too much.

    You asked about the domain objects, these are yet another class LibraryItem. Each of these has a type that corresponds to the id of the LibraryItemHelper . I chose to define my domain objects by composition instead of creating a class hierachy, so as to be able to add item types dynamically. It also keeps LibraryItem class very lightweight, suitable for use as a data transfer object. I'm loading this from another XML file, which I'll kep doing since this is purely the apps datastore.

    I think what it comes down to is getting used pushing some of the smarts in my app up to the Spring Layer. It seems that when I write an app, I wind up rolling my own, albeit simplified, spring-like mechanism for configuring factories, business rules, and wiring together object dependencies. Obviously, I have much of the support code for this sort of thing in place. It's my sense that in doing so I provide useful information to my self and to any one who comes along about the taxonomy and distribution of responsibilities of a particular application; information that aids in evolving an it over time.

    It seems to me that in giving this up I lose something, that I didn't lose when I stopped rolling my own object-relational mapping layer and started using Hibernate, or when started using Maverick instead of creating my own MVC layer.

    On the other hand, my clients don't pay me to be in the framework business, but to write applications. I think if the spring.net framework was evolved to the point of the java version, all of the additional features would make it a no-brainer to switch. As it stands, I'll probably make the refactorings you suggest and continue my experiment.

    Thanks,
    _______________
    Robert Moskal
    Most Media
    Brooklyn, USA

  4. #4
    Mark Pollack is offline Spring.NET Co-Lead Spring TeamSpring User
    Join Date
    Sep 2004
    Location
    New York, NY
    Posts
    1,683

    Default

    Hi Robert,

    I'll leave it to you to best refactor your code. In general, I think a good oo-design maps very nicely into a spring configuration file and in fact encourages good design. I don't agree that writing your own "DI"-ish support code provides more information to developers about the application structure or makes it more amenable to maintenance in the long term than using Spring - but I'll think through your viewpoint some more. BTW, the Spring.NET core IoC container functionality you are using is definitely on par with the Java version and I'd expect you would experience the same feelings if you were using Spring.Java. Let us know how it goes.

    Cheers,
    Mark

Posting Permissions

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