January 27, 2009, 4:56 pm
There are a lot of times in your application where you will load a lot of entities in a single session (to display a lot of data on a page, build a report, etc). Since you are not planning on doing a mutable operation on an entity, there is a big saving that you can get from not flushing the session. To get an idea on everything that happens when you do a flush, check out the AbstractionFlushingEventListener from the NHibernate source.
If you are using explicit SessionScope’s, not flushing the session is trivial:
1: using (new SessionScope(FlushAction.Never))
2: {
3: repository.DoSomeReadOperation();
4: }
This will execute the operation without flushing the session at the end.
Another way to control this behavior is by using an interceptor. For example, if you are using the Castle’s Automated Transaction Facility, you probably already have a way of determining whether or not your methods do mutable operations by their transaction attributes. You can then use an interceptor to control flushing:
1: public class UnitOfWorkInterceptor : IInterceptor
2: {
3: private readonly ITransactionManager transactionManager;
4:
5: /// <summary>
6: /// Initializes a new instance of the <see cref="UnitOfWorkInterceptor"/> class.
7: /// </summary>
8: /// <param name="transactionManager">The transaction manager.</param>
9: public UnitOfWorkInterceptor(ITransactionManager transactionManager)
10: {
11: this.transactionManager = transactionManager;
12: }
13:
14: #region Implementation of IInterceptor
15:
16: /// <summary>
17: /// Intercepts the specified invocation.
18: /// </summary>
19: /// <param name="invocation">The invocation.</param>
20: public void Intercept(IInvocation invocation)
21: {
22: ITransaction transaction = transactionManager.CurrentTransaction;
23: FlushAction flushAction = transaction == null ? FlushAction.Never : FlushAction.Config;
24:
25: ActiveRecordUnitOfWork.Before(flushAction);
26: invocation.Proceed();
27: ActiveRecordUnitOfWork.After();
28: }
29:
30: #endregion
31: }
Note that in this example, interceptor ordering is important. If you register the unit of work interceptor before the transaction interceptor in the ATM facility, then transactionManager.CurrentTransaction will always return null. (The ActiveRecordUnitOfWork class in the above example is just a facade for controlling the session in a thread local as discussed in this post http://erichauser.net/2008/08/06/activerecord-session-scope-and-wcf-redux/). If you do not want to tie your flushing to transactions, then you can always create your own metadata and read that metadata at runtime in the interceptor. The ATM facility code is a great example of how to inspect metadata on initialization and use that metadata in your interceptor.
Hopefully, this little trick will some increased performance for your queries that return a lot of results.
August 28, 2008, 8:30 pm
I have contributed a couple of enhancements to Castle.Components.Validator that have been committed to the trunk. Besides using attributes, validations can now be supplied in code using the [ValidateSelf] attribute:

Each of the above validations *could* be done by using an attribute and a custom validator, but expressing validations in code is much simpler for these types of one off validations. You can have as many methods decorated with [ValidateSelf] on an object you want as long as they have the above method signature (void return and one ErrorSummary parameter). You can also specify the RunWhen and ExecutionOrder just like regular validators.
The second enhancement is the IValidationContributor interface. This allows you contribute to the validation of an object beyond the default validation. The interface is fairly simplistic:

You can extend AbstractValidationContributor so that you can perform initialization for a given type. The SelfValidationContributor implements the logic for recognizing and executing the self validation feature above. You can write custom contributors that can be injected into the DefaultValidatorRunner for things like retrieving validations from the container and invoking them on the object.
Enjoy!
August 23, 2008, 10:59 am
I have added a couple of additions to Ayende’s NServiceBus Facility:
- Message handlers and sagas are automatically registered with the container for the defined assemblies
- Message handlers are proxied
- You can register IHandlerFilter instances with the kernel that allow for interception of messages as they are processed
- Using my replay strategy implementation, you can decorate a message handler as [Idempotent(Attemps = 5, Delay = 2000)]. That means that a message will be retried when an exception is thrown processing the message 5 times, delaying 2 seconds between each retry. This could also be extended so that depending on the type of exception that is being thrown, a default retry strategy is applied.

- The bus is started automatically once all handler dependencies have been satisfied
There were a couple of interesting things that I found when implementing this. One, NServiceBus retrieives handlers from the kernel using the concrete class instance (looking back Ayende noted this as “yuck”). That means that we cannot proxy the interface, but instead have to create a class proxy for our message handlers. That means that when we the message handlers, we have to verify that the message handler methods are virtual and give a nice error if they are not:

Very easy to do with Castle’s fluent interface for registration. Sagas, on the other hand, have to be registered in the container by each of their interfaces because saga instances are retrieve by calling builder.Build<ISaga<SomeMessage>>().
Out of the box, the way to do message interception with NSB is to have message handlers chained in a specified order. The IHandlerFilter provides another method for message interception. If you have a new filter to add, all you have to do is register the IHandlerFilter instance with the container:

The filters follow the chain of responsibility pattern, so they can be short circuited — which is the same as calling bus.DoNotContinueDispatchingCurrentMessageToHandlers().
I have attached the updates to the post: nservicebus-fullduplex-xml-update. Enjoy.