I really like test-driven development (TDD). I like the architecture that is forced upon you, and I definately like the quality output from the team. TDD simply works great, especially in combination with a continuous integration environment such as CruiseControl.Net or Microsoft Team Foundation Server.
So, of course I like to use tools or frameworks that enhance the TDD aspects of my projects. Or, to put it this way, I like tools and frameworks that enhance my projects, period. And Spring.Net... well, it really enhances my projects!
And, as an added bonus, you don't have to be too envious of those Java geeks talking about how great Spring is anymore. Great eh?
Spring.Net gives me access to:
* Inversion of Control (IoC) (http://en.wikipedia.org/wiki/Inversion_of_control)
* Aspect-Oriented Programming (http://en.wikipedia.org/wiki/Aspect-oriented_programming)
So, of course I'd like to use Spring.Net in my SharePoint projects. At the start, I was not so sure whether the technologies would work nicely together. But, let me assure you, after running it in two MOSS 2007 projects, I have still to find any problems with the combination.
Inversion of Control
By using Spring.Net I get a simple dependency injection running. It does create some hassle for the developer since dependencies between objects are now specified separately from the class file. But - we get the perfect TDD architecture running. Creating unit tests with mocking logic is now very simple. My junior developers also learn to code in a more structured fashion - with more "black box" design.
Do I apply dependency injection on all my objects then? No. So far I've only done this for Business and Data layers - that is, everything but the UI layer.
Why? For two reasons - it would complicate things for SharePoint, and well, I generally do not develop unit tests for user components anyhow since testing graphical interfaces is quite complex and expensive. Note that I make sure to keep logic in the UI layer at a bare minimum of course.
Aspect-oriented programming
Now, here's where the real fun begins. You do not see the value with dependency injection? Fine, you'll do well enough without it, especially with a good mocking framework.
But, using Spring.Net's dependency injection is required to get aspects working. Imagine the possible potential of developing your own aspects! So, have I created my own aspects? No. Quite frankly, so far I've only come around to using the built-in aspects available in Spring.Net. But boy, are they worth it.
One in particular stand out - the caching aspect. It uses the ASP.Net caching to work it's magic and since we're building a portal using SharePoint, it's a perfect fit. And lets face it - a portal will require a lot of caching to get the performance of a user-friendly site.
I've used several caching frameworks in my career (for example Microsoft Enterprise Library) and Spring.Net easily beats any other frameworks I've tested. Put simply, the caching aspect has saved weeks of work in my latest projects, and not once has it not worked as expected.
Time for an example:
In your data layer SettingsDac is responsible for retrieving and storing settings in your application. Settings are stored in a SharePoint list, but getting them from the list each time will impact on performance, so you want some caching.
This is the code, using Spring.Net and the caching aspect (a bit simplified):
[CacheResult(CACHENAME, "'Setting.Key=' + #key")]
public SettingsBE GetSetting(string key)
{
SPList list = GetSecurityElevatedList(LISTNAME);
// TODO: Validate list.
SPQuery query = new SPQuery();
query.Query = string.Format(QUERY_KEY, key);
SPListItemCollection listItemCollection = list.GetItems(query);
// TODO: Validate that we have exactly one result.
return CreateSetting(listItemCollection[0]);
}
As you can see, the only code the developer needs to get caching is the attribute CacheResult, the rest is done automatically (with the help of some configuration).
So, AOP might be complex sure, and all developers won't understand how it works, but frankly... When it's as simple as in the example above to use... do they have to understand it? As long as they get directives to, for example, only use it in DAC classes.
If you haven't tried out Spring.Net yet - do it now. You'll never regret it. :-)
Subscribe to:
Post Comments (Atom)

8 comments:
Great article. I have worked with a couple of Sharepoint WSS projects and I'm eager to try out Spring.Net with Sharepoint. Since I have been working with a lot of J2EE projects in the past I am aware of Spring's capabilities, at least from the Java-side of things.
In your use of Spring and Sharepoint do you have all access to the Sharepoint object model constrained to the data access layer?
How do you fit Sharepoint's Eventreceivers into the Spring architecture?
It would be great to hear more about your experiences with Spring and Sharepoint. I will try to find time to test that combination myself.
Thanks,
Mikael
Hi Mikael and thanks! :-)
Please understand that I'm not trying to represent any of SharePoints own framework in Spring, only the code produced by us.
Basically, our data access logic will call the SharePoint object model the "old-fashioned" way.
The same goes for event receivers. My custom event receivers will however only consist of a thin layer that passes on any events to the business layer using the Spring context.
Not really considered whether I should strive to extend the Spring context further, but I don't think I can see much value in it since I won't care to run either TDD or AOP on SharePoint's own framework.
Have fun! :-)
Hi Terborn,
Presently i am working on share point(MOSS2007) project and we are trying to configure Spring.net in Share point,But we are facing problems while configuring Spring.net Object in Web.config of Share point Sever.
Can you please Give the Details of Configuring Spring.net in Share point.
Thanks,
And How to use Spring.net in Share point.
Hi Vinay,
I've run MOSS + Spring.Net with spring configuration in web.config, so it works. Just add the configSection and spring element, and it should work.
However, in my new projects I've chosen to use a separate configuration file instead. In a farm you may have several machines and even if you could use the SPWebConfigModification class to deploy changes it is a cumbersome process. Especially with future upgrades in mind.
Instead I suggest that you put your spring configuration in a seperate XML that you embed in your application.
The process for doing this is explained here (chapter 5.2.2):
http://www.springframework.net/doc-latest/reference/html/objects.html#objects-basics
Good luck!
I've seen comments that Spring.Net only works under full trust. Would you mind posting some info on the steps to enable Spring in SharePoint?
Hi Rich,
You may very well be right on the full trust issue. Quite frankly, I've never had to think about that issue since I've always deployed my DLLs to GAC, thus giving them full trust automatically.
The Spring DLLs are deployed to the GAC as well using the following markup in manifest.xml:
<Assembly DeploymentTarget="GlobalAssemblyCache" Location="Spring.Core.dll" />
<Assembly DeploymentTarget="GlobalAssemblyCache" Location="Spring.Aop.dll" />
<Assembly DeploymentTarget="GlobalAssemblyCache" Location="Spring.Web.dll" />
Since the Spring.Net logic is otherwise contained within my DLLs everything works nicely without additional work.
(Besides moving spring bindings from web.config to an embedded resource, as I mentioned above.)
I've been wondering, how do you get access to objects in the spring context from something like a web part? Can you use dependency injection? If not, how do you get access to the spring context?
Hi, and sorry the delay in answering.
I get hold of objects from the spring cache by having a "BusinessFactory" class containing properties similar to this:
public static ISettingsBC GetSettingsBC()
{
return (ISettingsBC)mContext.GetObject(NAME_SETTINGSBC);
}
How the context itself is loaded depends on where you store your your spring bindings of course.
This is an example from loading a spring context from an XML stored as a resource file:
private static IApplicationContext mContext = SpringContext;
// Elsewhere...
mContext = new XmlApplicationContext(ASSEMBLY_LOCATION);
ContextRegistry.RegisterContext(mContext);
Hope that'll be of help!
Post a Comment