Presentation: Introduction to Spring.Net

Last Thursday my boss and I gave a presentation on Spring.Net and dependency management in general. The audience mainly, if not only, consisted of students in their 2nd or 3rd year so they probably wondered what all the fuzz was about. I just hope that they will remember the concepts we introduced to them and understand that there’s more to software development than the typical three tier applications you develop in school.

If you were in the audience and have questions on the topic or presentation, feel free to contact me at: me[at]bennymichielsen[dot]be .

The first few slides are based on and contain images from a presentation by Bob Martin and is available on InfoQ. The sample which introduces AOP and has an implementation of INotifyPropertyChanged is based on a sample you find in the Examples directory when you install Spring.Net.

Keynote Presentation:

Introduction.key (730.08 kb)

PDF Version:

Introduction.pdf (1.37 mb)

Samples:

SpringSamples.zip (2.65 mb)

Add aspects at runtime without xml to your spring context

A user on the Spring.Net forum asked if it was possible to apply an interceptor at runtime to certain classes without resorting to xml. It turned out to be rather easy to accomplish this and encourages me to look deeper into enabling something like Fluent NHibernate for Spring.Net.

The key interface in this story is “IObjectPostProcessor”. It enables you to edit an object after it has been instantiated and populated by Spring.Net.

public interface IObjectPostProcessor
{
	object PostProcessAfterInitialization(object instance, string objectName);
 
	object PostProcessBeforeInitialization(object instance, string name);
}

The documentation states that the processors that populate entities via marker attributes should use the “PostProcessBeforeInitialization” where as postprocessors that wrap objects with proxies should use “PostProcessAfterInitialization”. In this case it’s clear that since we will create a proxy we need to implement the latter.

public object PostProcessAfterInitialization(object instance, string objectName)
{      
	if (InstanceShouldBeProxied(instance))
	{
		ProxyFactory factory = new ProxyFactory(instance);
		factory.AddAdvice(new WriteLineAspect());
		return factory.GetProxy();
	}
	return instance;
}

The implementation is rather straightforward. The postprocessor has a collection of all the types it should intercept and checks each instance it is handed. If there is a match it will create a proxyfactory, add the advice and create a proxy. Otherwise it just returns the instance.

The application context in Spring automatically picks up any processors it has and will hook it up for you. When deployed in an objectfactory however you need to explicitly register it.

The only thing left to add now is the configuration part for the postprocessor which is demonstrated in the sample below.

private static void RegisterPostProcessor(GenericApplicationContext context)
{
	MyPostProcessor postProcessor = new MyPostProcessor();
	postProcessor.InterceptInstancesOfInterface(typeof(ITaksService));
	context.ObjectFactory.AddObjectPostProcessor(postProcessor);
}

Full source code is available here: Program.cs (3.50 kb)

Using Fluent NHibernate in Spring.Net

In order to load the mappings you’ve written using Fluent NHibernate you need to call the extension method “AddMappingsFromAssembly” on the configuration. The “LocalSessionFactoryObject” defined in Spring.Net supports out of the box the loading of .hbm files from an assembly or a location in the file system. Luckily this class can be extended with ease. The code below is all you need to use Fluent NHibernate with Spring.Net, any suggestions for a better name are welcome.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Data.NHibernate;
using FluentNHibernate;
using System.Reflection;
using NHibernate.Cfg;
 
namespace SessionFactories
{
    public class FluentNhibernateLocalSessionFactoryObject
	: LocalSessionFactoryObject
    {
        /// <summary>
        /// Sets the assemblies to load that contain fluent nhibernate mappings.
        /// </summary>
        /// <value>The mapping assemblies.</value>
        public string[] FluentNhibernateMappingAssemblies
        {
            get;
            set;
        }
 
        protected override void PostProcessConfiguration(Configuration config)
        {
            base.PostProcessConfiguration(config);
            if(FluentNhibernateMappingAssemblies != null)
            {
                foreach(string assemblyName in FluentNhibernateMappingAssemblies)
                {
                    config.AddMappingsFromAssembly(Assembly.Load(assemblyName));
                }
            }
        }
    }
}

Update 29 June: please check the comments since a new version brought some changes to this blog post.

Adding transactions and exploring the BindingList

I stopped working on my todo sample after all the frameworks were playing nicely together and my todo list was displayed. Next up was adding edit capabilities.

At work I normally use Spring.Aop to inject an INotifyPropertyChanged implementation into the objects I pass to the view, but since I’m trying out new stuff here I turned to the default .Net BindingList to support change notification. I’m actually quite happy with the capabilities that are provided, for now at least. The BindingList has a ListChanged event which gets fired if either a property of an object in the list gets changed or the list itself is modified. For my basic sample here this is more then enough. Something I struggled with however, was how to turn off notifications while the list is being populated with data which improves responsiveness of the UI. After some googling I found that you had to call ResetBindings, strange that I didn’t find anything on MSDN that told me how to work in this scenario. I might need to pick up a book on Windows Forms development though, professionally I work with WinForms 99% of the time when I need to create a UI, who knows what other ‘goodies’ I’m missing out on.

public void SetDatasource(List<TodoDto> todos)
{
    todoDtoBindingSource.RaiseListChangedEvents = false;
    todoDtoBindingSource.DataSource = todos;
    todoDtoBindingSource.RaiseListChangedEvents = true;
    todoDtoBindingSource.ResetBindings(false);
}

With the UI now raising events when the user makes changes, the presenter that is listening had to keep track of the changes and forward them to the webservice when the user wants to save his work. The code I’ve written for that isn’t rocket science or hard to grasp. It boils down to what is transferred between the client and the server.

public enum ChangeType
{
    Added = 0,
    Changed,
    Deleted
}
 
public class TodoEditDto
{
    public virtual Guid EditId { get; set; }
    public virtual TodoDto EditedTodo { get; set; }
    public virtual ChangeType ChangeType { get; set; }
}

The ChangeType indicates what has happened, the item was added, changed or deleted. The TodoEditDto wraps the edited dto, adds a ChangeType and EditId property. The EditId is generated on the client and used to identify newly saved objects when the server sends back the Id’s that were generated when the todo was persisted. That way a new created todo can be edited right away after saving it.

// saved data to server
foreach (var persistedEdit in response.PersistedEdits)
{
    var foundEdit = (from edt in editedTodos
                     where edt.Value.EditId.Equals(persistedEdit.EditId)
                     select edt.Value).First();
    foundEdit.EditedTodo.Id = persistedEdit.EditedTodo.Id;
}

With some basic editing now in place, some work is still needed in the UI, let’s now add transactional support to our save method. Spring.Net allows you to add this capability declarative or programmatic and even within these two approaches there are several ways to achieve your result. At work I’ve always used the declarative way using AutoProxy and the [Transaction()] attribute. To make that work you need to add a reference to Spring.Data, add the attribute to the methods that need to be transactional and add the following object definitions to your configuration.

<object id="AutoProxyCreator" 
		type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/>
 
<object id="TransactionAdvisor"
		type="Spring.Transaction.Interceptor.TransactionAttributeSourceAdvisor, Spring.Data">
		<property name="TransactionInterceptor" ref="TransactionInterceptor"/>
</object>
 
<!-- Transaction Interceptor -->
<object id="TransactionInterceptor"
		type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
		<property name="TransactionManager" ref="TransactionManager"/>
		<property name="TransactionAttributeSource" ref="AttributeTransactionAttributeSource"/>
</object>
 
<object id="AttributeTransactionAttributeSource"
	type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data">
</object>
[Transaction(TransactionPropagation.Required)]
public SaveEditedTodosResponse SaveTodos(SaveEditedTodosRequest request)
{
    // do stuff
}

At runtime, Spring.Net will create a proxy for each service that has the tranascation attribute declared on its methods and manage the transaction from in that generated class. Everything you’ve written will be transactional from that point until the method that is being called is completed. For now however, let’s use the TransactionProxyFactoryObject. To use this approach I only need to change my service definition. Through the transaction attributes property I can define which methods need to be transactional, in this case any method that starts with Save. The target property can be any object in your context.

<object id="TodoService" 
		type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data">
	<property name="PlatformTransactionManager" ref="TransactionManager"/>
	<property name="TransactionAttributes">
		<name-values>
			<add key="Save*" value="PROPAGATION_REQUIRED"/>
		</name-values>
	</property>
	<property name="Target">
		<object type="TodoCore.AppService.TodoService, TodoCore">
			<property name="TodoRepository" ref="NhnTodoRepository"/>
		</object>
	</property>
</object>

With this in place we now have a basic application which is workable in a test environment. Speaking about tests, I really need to add them to the project. I’m not a very good TDD’er myself, though I’m convinced it is the way to go. I should start applying it.

SampleApplication04092008.rar (2.95 mb)

Using Spring.Net, SQLite and NHibernate

I was planning to put a quick spike together on putting single sign-on, using CardSpace, OpenID and Windows Live, into an application to test it out for a project at work. Maybe it was because of the weekend, but I was quite enthusiastic and added several technologies to the sample which I had never used before. Six hours later, there was still no single sign-on or even a fully working sample application to add the behaviour to. So instead of posting one post, I’ll have a mini series where SSO will actually be a side track.

Getting the database set up was one of the first things I wanted to do. I didn’t want to add a MS SQL database to the project since that would require anyone who downloaded this project to have the database engine running. On various other blogs and .Net sites I’ve read there was talk about a lightweight alternative in the form of Sqlite. The .net provider can be downloaded here and boy was I lucky, the day I wanted to try it out they released a new version. Their latest version includes designer support in Visual Studio. Halfway august the Spring.Net team had also released a new version (1.2 M1) so I grabbed that version and NHibernate went 2.0 GA as well.

Since the Spring.Net assemblies are strongly signed they expected SQLite 1.0.56 and not 1.0.58 which was the one I downloaded. To make use of the new dll’s I added this to my configuration.

<db:provider id="DbProvider" provider="SQLite-1.0.56" connectionString="${db.datasource}"/>

Spring.Net has several DbProviders already configured, one of them being for version 1.0.56. Normally you don’t want to configure the entire provider for a new version so I just reused the existing configuration and added an assembly redirect.

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
    <assemblyIdentity name="System.Data.SQLite" culture="neutral" publicKeyToken="db937bc2d44ff139"/>
    <bindingRedirect oldVersion="1.0.56.0" newVersion="1.0.58.0"/>
  </dependentAssembly>
</assemblyBinding>

This is all defined in the spring manual, but it actually took me quite some time to get it running. Only when adding the xml namespace the redirect was picked up when running the application. The NHibernate version I had was also newer so a redirect was necessary for those dll’s as well.

With this out of my way I still had to tell NHibernate to use SQLite. The official site gives this sample configuration:

<?xml version="1.0" encoding="utf-8"?>
  <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
    <session-factory name="NHibernate.Test">
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      <property name="connection.driver_class">NHibernate.Driver.SQLiteDriver</property>
      <property name="connection.connection_string">
				Data Source=nhibernate.db;Version=3
      </property>
      <property name="dialect">NHibernate.Dialect.SQLiteDialect</property>
      <property name="query.substitutions">true=1;false=0</property>
    </session-factory>
  </hibernate-configuration>

Which is almost correct, but not quite. Below you find the complete correct springified configuration, so extract the pieces you need when using plain NHibernate. The difference is in the driver class.

<object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate20">
  <property name="DbProvider" ref="DbProvider"/>
  <property name="MappingAssemblies">
    <list>
      <value>TodoCore</value>
    </list>
  </property>
  <property name="HibernateProperties">
    <dictionary>
      <entry key="connection.provider"
			 value="NHibernate.Connection.DriverConnectionProvider"/>
      <entry key="connection.driver_class" 
             value="NHibernate.Driver.SQLite20Driver"/>
      <entry key="dialect" 
             value="NHibernate.Dialect.SQLiteDialect"/>
      <entry key="query.substitutions" 
             value="true=1;false=0"/>
    </dictionary>
  </property>
  <property name="ExposeTransactionAwareSessionFactory" value="true" />
</object>

Great we’ve configured our data access! But the repository is giving me errors, it can’t find the database file. The project structure I have is illustrated below.

My first attempt was to use relative path names.

<add key="db.datasource" value="Data Source=~App_DataTodoDb.db;Version=3;"/>

But that just failed, to get this working I used the, for me, new |DataDirectory| variable which did cause the database to be found and used.

<add key="db.datasource" value="Data Source=|DataDirectory|TodoDb.db;Version=3;"/>

The data was now being retrieved, isn’t that wonderful, only took me maybe two or three hours. As front end I first added a WPF application, but if you see that Window1.xaml file for the first time you have a bit of a writer’s block. Even when you drag a button on it, you don’t get to see one and adding a grid to the window and then trying to add a column was quite overwhelming, there even seem more options available compared to the third party components I use at work. So for now just good old Winforms, but a WPF front end will definitely be added. I also played around with the bindinglist you can create when using a grid, I must admit I’ve never used it before. I’ve always used my own implementation, we’ll see where it goes when I add an edit mode to the application. So for now I can only give you a configured application which shows your todos, so basically the same setup as my last spring.net sample which illustrated the support for webservices.

SampleApplication.rar (2.74 mb)

And before anyone asks, yes tests should be added.

Using appSettings in your Spring configuration

This seems to be an undocumented feature that someone asked about on the user forum of the Spring.Net framework, I don’t know where I picked it up so I’m writing it down here.

When using .Net you tend to put configuration values in the appSettings section of your app or web.config. Entries like filepaths or other constants fit here nicely. If you’ve written an application powered by Spring.Net you’ll also have several spring configuration files which define the objects in use by your system. Most of their dependencies (if not all) are quite static but sometimes there’s the need for a configurable value. These tend to change more than other object relations so instead of searching through all your definitions to change them wouldn’t it be better to have a central place where you can manage them? Of course it would, so let’s use the appSettings section!

In order to reference the appSettings in your Spring configuration file you need to add this object definition to your configuration:

<object name="appConfigPropertyHolder" type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
  <property name="configSections">
    <value>appSettings</value>
  </property>
</object>

Your appSettings typically looks like this:

<appSettings>
  <add key="LoggerOutputFile" value="c:MyOutputFile.txt"/>
</appSettings>

Now you can reference this value using ${“LoggerOutputFile”} as illustrated below.

<object name="MyLogger" type="SpringAppSettingsConsole.Infrastructure.FileLogger, SpringAppSettingsConsole">
  <constructor-arg  value="${LoggerOutputFile}"/>
</object>

Full sample with source code can be downloaded here: SpringAppSettings.zip (247.31 kb)

Building webservices with Spring.Net

Building and consuming anything but a trivial web service with Visual Studio can be quite an error prone task. The service itself is difficult to test outside of the web environment, the proxy class generated by Visual Studio will, most of the time, be in a conflicted state in your code repository as multiple developers add and change methods. It’s also quite cumbersome if you want to map those proxy classes back to your own classes. The list goes on and while Windows Communication Foundation does solve some of these issues I’d like to introduce you to the service infrastructure of Spring.Net which can help you to expose your services and is available on .net 2.0.

Let’s first look at the server side. Instead of decorating your service with webservice and webmethod attributes you can write a plain old c# object (poco) which can be tested like any other class and be hosted in multiple environments, exposing the service via remoting is just a configuration change. Nothing even prevents you from making a fat client, just keep the service itself behind an interface.

public class ProductService
: IProductService
{
	private List<ProductDto> products;
 
	public ProductService()
	{
		products = new List<ProductDto>();
		products.Add(new ProductDto("Pizza Margherita",9.75));
		products.Add(new ProductDto("Pizza Pepperoni Lovers",10.95));
		products.Add(new ProductDto("Pizza Cheesam ",10.95));
	}
 
	#region IProductService Members
 
	public RetrieveProductsResponse RetrieveProducts(RetrieveProductsRequest request)
	{
		return new RetrieveProductsResponse(products);
	}
 
	public SearchProductsResponse SearchProducts(SearchProductsRequest request)
	{
		List<ProductDto> productMatches = new List<ProductDto>();
		foreach (ProductDto product in products)
		{
			if (product.Name.ToUpper().Contains(request.Name.ToUpper()))
			{
				productMatches.Add(product);
			}
		}
		return new SearchProductsResponse(productMatches);
	}
 
	#endregion
}

As you can see, nothing fancy here. The ProductDto, requests, responses and the service interface are all located in an assembly which will be shared between the client and the server.

Whenever you build a service layer around your application, the best way to look upon it is like a GUI. You expose the behaviour of your domain, just not with web or winforms.

Since the service is just a poco, putting it into your spring configuration is just like you would add any other class. You can perform DI, AOP, … upon it like you’d normally do.

<object name="ProductService" type="Service.ProductService, Service"/>

To make it available as a webservice you use the Webservice exporter which can be found in the Spring.Web assembly as illustrated below.

<object id="ProductWebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
  <property name="TargetName" value="ProductService"/>
  <property name="Namespace" value="http://www.bennymichielsen.be/services"/>
  <property name="Description" value="Defines operations upon products"/>
  <property name="MemberAttributes">
    <dictionary>
      <entry key="RetrieveProducts">
        <object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
          <property name="Description" value="Retrieves all products"/>
          <property name="MessageName" value="RetrieveProducts"/>
        </object>
      </entry>
      <entry key="SearchProducts">
        <object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
          <property name="Description" value="Searches for products which have a name like the one supplied."/>
          <property name="MessageName" value="SearchProducts"/>
        </object>
      </entry>
    </dictionary>
  </property>
</object>

Using the Webservice exporter you can export any object in your configuration as a webservice, just point it to the appropriate object definition using the TargetName property. I’ve populated some more properties just to show how you can use this class. It is however necessary to have an interface(s) on your service, but since this is a best practice anyhow I don’t see this as a shortcoming.

On the client side a similar approach can be used to consume the webservice using the WebserviceProxy factory in the Spring.Services assembly. Using this class your code can depend upon the service interface instead of the proxy class itself. If you want to use the proxy class, this is still supported. In this case Spring will create a proxy which will implement the service interface and map to the Visual Studio proxy. Note that the original service does not have to implement this interface, the methods supplied in the interface are mapped using a kind of duck typing. This is very useful if you don’t control the service but are consuming it and don’t want to tightly couple your code.

If you do control both sides, it is much easier to let the proxy be generated at runtime.

<object name="ProductService" type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services">
  <property name="ServiceUri" value="http://localhost:1871/ProductWebService.asmx"/>
  <property name="ServiceInterface" value="ServiceContract.Interface.IProductService, ServiceContract"/>
</object>

This allows you to use the service interface, the concrete implementation is of no concern. What’s also very useful is that you can reuse all the classes which are already in the service contract assembly, thus preventing your solution from being polluted with any additional code.

For more information please take a look at the documentation.

SpringWebservicesSample.zip (1.22 mb)

Adding object definitions from non-local classes

On the Spring forum someone asked if it was possible to add object definitions to the application context of classes which were beyond the searchable range of the application. I was a little bit sceptic at first but one debugging session later, I found out that it is possible to do this. Though I really don't support the whole idea of doing this.

When you are not using fully qualified assembly names in your definition Spring will look at the current loaded assemblies to resolve the type, so with this trick you can make it work. The topic can be found here and the source code can be found here, don't forget to change the path of the “ClassLibrary1” assembly to make it work.

class Program
{
	static void Main(string[] args)
	{
		Assembly.LoadFile(@"C:MyPathToSomeDllClassLibrary1.dll");
		object o = ContextRegistry.GetContext().GetObject("MyObject");
		Console.WriteLine("Retrieved object from context");
		Console.ReadLine();
	}
}

<objects xmlns="http://www.springframework.net" >
  <object id="MyObject"
          type="ClassLibrary1.Class1">
    <property name="Test" value="MyTestValue"/>
  </object>
</objects>