The S#arp Architecture Contrib team believes that most developers using S#arp Architecture in non-web applications want to leverage work already done in a web application. For example, you might need a web service to run background processing tasks for your web application. Therefore, this how-to focuses on adding a Windows application to an existing solution that already has a working web. If you don't have a working web yet, you can use the solution template that comes with S#arp Architecture to create one.
Note that you no longer need to use PostSharp with Contrib as it now uses Castle Interceptors
EditSetup
Your project must configure NHibernate and Castle Windsor at startup.
Step 1: NHibernate Configuration File
Add a link to your web's NHibernate.config to your Windows application. If you are unsure how to do this, check out the information on adding an item as a link in this Microsoft article
How to: Add Existing Items to a Project.
Step 2: Move <Your Project>.Web.CastleWindsor.ComponentRegistrar to a Shared DLL
<Your Project>.Web.CastleWindsor.ComponentRegistrar will need to be accessed by your Windows application. Of course, you cannot reference your web DLL from your Windows application so it will have to be moved to a common location. Arguably, this is an application service and can be moved to <Your Project>.ApplicationServices.CastleWindsor.
Step 3: Create a Static Class to Initialize Service Locator
Add the following class to <Your Project>.ApplicationServices.CastleWindsor:
using Castle.Windsor;
using CommonServiceLocator.WindsorAdapter;
using Microsoft.Practices.ServiceLocation;
namespace <Your Project>.ApplicationServices.CastleWindsor {
public static class ServiceLocatorInitializer {
public static void Init() {
IWindsorContainer container = new WindsorContainer();
//Register all the Contrib Components
SharpArchContrib.Castle.CastleWindsor.ComponentRegistrar.AddComponentsTo(container);
ComponentRegistrar.AddComponentsTo(container);
ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
}
}
}
Step 4: Create a Static Class to Initialize NHibernate
Add the following class to <Your Project>.Data:
using <Your Project>.Data.NHibernateMaps;
using SharpArch.Data.NHibernate;
using SharpArchContrib.Data.NHibernate;
namespace <Your Project>.Data {
public static class Initializer {
public static void Init() {
NHibernateSession.Init(new ThreadSessionStorage(),
new[] {"<Your Project>.Data.dll"},
new AutoPersistenceModelGenerator().Generate(),
"NHibernate.config");
}
}
}
Notice that this configuration is using ThreadSessionStorage, which is required if you will be using the UnitOfWork support. If you are using the Transaction attribute you can still use WebSessionStorage.
Step 5: Initialize Service Location and NHibernate When Application Starts
Make sure to call <Your Project>.ApplicationServices.CastleWindsor.ServiceLocatorInitializer.Init() followed by <Your Project>.Data.Initializer() when your application starts.
Important!: Make sure you register the components from SharpArchContrib
before registering any components from your project. Failing to do this will result in castle not recognizing the
Transaction or
UnitOfWork attributes since the interceptor has not been registered yet.
EditSession Management
For best results you should attribute any method that performs NHibernate operations with the UnitOfWork attribute. The UnitOfWork attribute will ensure that your application adheres to best-practices when using NHibernate. Review the documentation on UnitOfWork for more information.