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)

Leave a Reply

Your email address will not be published. Required fields are marked *