Corey Coogan

Python, .Net, C#, ASP.NET MVC, Architecture and Design

  • Subscribe

  • Archives

  • Blog Stats

    • 47,174 hits
  • Meta

Archive for the ‘Uncategorized’ Category

StructureMap + WCF + NHibernate Part 2

Posted by coreycoogan on May 27, 2010

Introduction

In Part 1 of this two part series, I showed what it takes to create a library that will enable Dependency Injection in WCF services by leveraging the extension points in the WCF pipeline. My solution had very slight modifications to what was provided by Jimmy Bogard with plans for extending to allow an NHibernate (NH) Session/Call pattern in WCF utilizing StructureMap (SM).

In this post I’ll show my implementation, derived from the solution posted on Real Fiction, that is built on top of my Wcf.IoC library. This library will be responsible for getting a single ISession opened at the start of each call, injecting it into all dependent classes and then flushing and disposing it at the end of the call.

Why Session per Call?

Session per Call, also known as Session per Request, is the pattern where the application is given the responsibility of opening an ISession (DataContext or other UnitOfWork) and then disposing of it at the end of the call. Some variations of this pattern may also open an ITransaction at the beginning of the call and Commit or Rollback at the end. I prefer to return a status in my service response when something goes wrong, therefore I give the service the responsibility of creating and managing transactions. This way I can catch exceptions and react accordingly.

Employing this technique has several advantages.

  • Once setup, developers don’t have to worry about the ISession and where it comes from.
  • Once setup, developers don’t have to worry about properly disposing of the ISession when they are done with it.
  • If there are unhandled exceptions, the ISession is always disposed.
  • Ensures a single ISession is created and used by the service and component dependencies, thereby reducing resource consumption.

First, a special point of emphasis on the last bullet above, which is very important to get the full benefit of the Session/Call pattern we’re implementing here. For this to work, any classes that depend on an ISession must be configured to have an ISession injected into them (I prefer constructor injection for this). It is important that your components don’t configure ISession resolution, but rather let the application handle this detail. To learn more about configuring components from your application using StructureMap, have a look at this post on the topic.

NHibernate Session Context

To ensure the same NHibernate session is used throughout the WCF service call we’ll need to store the session somewhere. In a web application, this place is typically the HttpContext. In WCF, this is done by creating and adding an extension to the InstanceContext, which is basically a storage area scoped to the instance of the service object.

To do this, we simply implement the IExtension<> interface with a class that is responsible for holding a reference to the call’s ISession object and handles Flush and Disposal when the call is over. My implementation here is just like that of the inspiring post with the exception of my try/catch around the Session disposal.

/// <summary>
/// Holds a reference to an NH ISession and gets cached in the InstanceContext of a
/// WCF call.
/// </summary>
public class NhContextManager : IExtension<InstanceContext>
{
	public ISession Session { get; set; }

	public void Attach(InstanceContext owner)
	{
	}

	public void Detach(InstanceContext owner)
	{
		if (Session != null)
		{
			try
			{
				Session.Flush();
				Session.Dispose();
			}
			catch (Exception ex)
			{
				//log the error but don't throw
			}

		}

	}
}

IInstanceProvider

We’ll use a custom IInstanceProvider to add our Extension into the InstanceContext. This is a very straight forward process, as you’ll see. In Part 1 I showed the custom IInstanceProvider implementation that used SM to create an instance of the requested service. We’ll derive our NH Session-aware InstanceProvider from this one so we can add our extension before resolving the type from SM.

public class NhInstanceProvider : IocInstanceProvider
{
	public NhInstanceProvider(Type serviceType) : base(serviceType)
	{

	}

	public override object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
	{
		//add the NH Session manager to the context of this WCF request
		var nhSessMgrExtension = instanceContext.Extensions.Find<NhContextManager>();
		if (nhSessMgrExtension == null)
			instanceContext.Extensions.Add(new NhContextManager());

		//let the base handle the IoC resolution
		return base.GetInstance(instanceContext, message);
	}

	public override void ReleaseInstance(InstanceContext instanceContext, object instance)
	{
		var nhSessMgrExtension = instanceContext.Extensions.Find<NhContextManager>();
		if (nhSessMgrExtension != null)
			instanceContext.Extensions.Remove(nhSessMgrExtension);

		base.ReleaseInstance(instanceContext, instance);
	}

}

Setting the NhContextManager.Session Property

The NhContextManager’s Session property is what will be used access the current call’s open ISession object. Remember that the NhContextManager is just our way of storing the ISession in the context of the call. This is where we’ll utilize the ISessionFactory.GetCurrentSession() extension point that was graciously granted to us by NHibernate for things just like this.

NHibernate’s ISessionFactory interface has a method, GetCurrentSession(), intended for getting a contextual instance of a session. Getting this working requires two steps.

First, we must create an implementation of the ICurrentSessionContext interface. This is what NHibernate will use to get an open session when one is requested from the GetCurrentSession() method. The other step is to tell the NHibernate configuration what our implementation of ICurrentSessionContext is so it knows how to respond to GetCurrentSession() calls.

ICurrentSessionContext Implementation

First thing to notice is that the constructor takes an ISessionFactory instance. This is required for getting an open Session the first time. The CurrentSession() method is where all the work is done. First, search extensions on the InstanceContext and find the NhContextManager instance. Now get the Session from the NhContextManager.Session property. If it’s there, we’ll return it. If it’s not there, we’ll open a new one, set it on the NhContextManager object, then return it. This is the nuts and bolts of getting this whole thing working. By delegating the ISession.CurrentSession() method to use the WCF instance context, we are ensuring a single open ISession is used for each WCF service instance, which is created once per call.

public class WcfSessionContext : ICurrentSessionContext
{
	private readonly ISessionFactory _factory;
	public WcfSessionContext(ISessionFactory factory)
	{
		_factory = factory;
	}

	public ISession CurrentSession()
	{
		// Get the WCF InstanceContext:
		var contextManager = OperationContext.Current
			.InstanceContext.Extensions.Find<NhContextManager>();

		if (contextManager == null)
		{
			throw new InvalidOperationException(
				@"There is no context manager available.
				Check whether the NHibernateContextManager is added as InstanceContext extension.
				Make sure the service is being created with the NhServiceHostFactory.
				This Session Provider is intended only for WCF services.");
		}

		var session = contextManager.Session;
		if (session == null)
		{

			session = _factory.OpenSession();

			contextManager.Session = session;
		}

		return contextManager.Session;
	}
}

Setting up NHibernate with our ICurrentSessionContext Implementation

Now we have to tell NHibernate what we want to use to extend the ISessionFactory.GetCurrentSession() method. This may seem a bit goofy, but it works. Before building the SessionFactory, we add a property to the NHibernate.Cfg.Configuration using the necessary magic string and the fully qualified type of our ICurrentSessionContext class.

NOTE: this step would be done by the application in the BootStrapper, where NHibernate initialization should be taking place.

void AddCurrentSessionImpl(NHibernate.Cfg.Configuration config)
{

var sessionContextType = typeof (WcfSessionContext);

            var currentSessionContextImplTypeName = sessionContextType.FullName + ", " +
                                                    sessionContextType.Assembly.FullName;

            var props = config.Properties;
            if(props==null)
            {
                props = new Dictionary<string, string>();
                config.AddProperties(props);
            }

            props.Add("current_session_context_class", currentSessionContextImplTypeName);
}

Configuring StructureMap for ISession Resolution

Since we are relying our StructureMap to handle the Dependency Injection of our services, it must be configured to get our ISession from the ISessionFactory.GetCurrentSession() method. Even though StructureMap is to returning a transient instance, which is the default behavior, we’re trusting our WcfSessionContext to give us the same instance per WCF service call.

The best way to do this is create an SM Registry in our Wcf.NHib library. Our Registry will take an instance of an ISessionFactory. This is required so that our application can configure and initialize NHibernate however the application requires and then let our Wcf.Nhib library handle the specific registration. In this way, the library can be leveraged across any number of WCF services that have their own distinct NHibernate configurations.

/// <summary>
/// A StructureMap registry for telling the container how to resolve an ISession request.
/// This must be instantiated and added to the SM configuration so it has an instance of the
/// SessionFactory to use.
/// </summary>
public class WcfNHibernateRegistry : Registry
{
	public WcfNHibernateRegistry(ISessionFactory sessionFactory)
	{

		For<NHibernate.ISession>()
			.Use(() => sessionFactory.GetCurrentSession())
			;
	}
}

Ensuring the Proper IInstanceProvider Implementation

The lowest level object in our WCF pipeline is the InstanceProvider, which is responsible for creating the instance of our service, fully injected with Repositories, ISession, and whatever else is necessary. To make sure my NhInstanceProvider is used throughout the WCF call pipeline, I’ll want to implement a custom ServiceBehavior, ServiceHost and ServiceHostFactory. Luckily, I can just derive from the classes created in my Wcf.IoC library and override the necessary pieces. This is pretty simple and ensures that my service is both DI-enabled and Session/Call aware.

ServiceBehavior

All I have to do here is construct my NhInstanceProvider.

public class NhServiceBehavior : IocServiceBehavior
{
	/// <summary>
	/// A Func that takes the ServiceType in the constructor and instantiates a new IInstanceProvider.
	/// Defaults to an IocInstanceProvider
	/// </summary>
	public override Func<Type, IocInstanceProvider> InstanceProviderCreator
	{
		get
		{
			return (type) => new NhInstanceProvider(type);
		}
	}

}

ServiceHost

The custom ServiceHost has a little more custom code. We’re going to derive from the IocServiceHost to meet our IoC requirement. We’ll override the ServiceBehavior method where we’ll create an instance of the NhServiceHost. Before we return our instance though, we’ll make one modification.

Since our Session/Call implementation requires that WCF is operating in PerCall mode, let’s make sure that’s always the case by forcing that setting. If we use a stateful mode, we may run into the danger of the same ISession being shared between calls which could lead to all sorts of obvious problems.

To do this, we simply find the ServiceBehaviorAttribute of the service instance. If it’s not there, we’ll add it. Now it’s just a matter of setting the InsntaceContextMode property to InstanceContextMode.PerCall.

public class NhServiceHost : IocServiceHost
{
	public NhServiceHost(Type serviceType, params Uri[] baseAddresses)
		: base(serviceType, baseAddresses)
	{
	}

	public override IocServiceBehavior ServiceBehavior
	{
		get
		{
			var behavior = Description.Behaviors.Find<ServiceBehaviorAttribute>();
			if (behavior == null)
			{
				behavior = new ServiceBehaviorAttribute();
				Description.Behaviors.Add(behavior);
			}
			//force PerCall to ensure a single session is not shared
			behavior.InstanceContextMode = InstanceContextMode.PerCall;

			return new NhServiceBehavior();
		}
	}
}

ServiceHostFactory

The ServiceHostFactory, like the ServiceBehavior, will do nothing more than override the SvcHost property to ensure that the NhServiceHost is used when the IocServiceHostFactory asks for a ServiceHost instance.

public class NhServiceHostFactory : IocServiceHostFactory
{
	protected override Func<Type, Uri[], IocServiceHost> SvcHost
	{
		get
		{
			return (type, uri) => new NhServiceHost(type, uri);
		}
	}
}

Now all we need to do to get our NH Session/Call wired up is edit the markup of our .SVC files and tell it what factory to use.

<%@ ServiceHost
Language="C#"
Service="Service.ProfileService"
CodeBehind="ProfileService.svc.cs"
Factory="Wcf.NHib.NhServiceHostFactory,Wcf.NHibernate"
 %>

What This Gets Us

Now that we’ve jumped through all these hoops, what’s the payoff? We now have the ability to write a service that looks like this.

public class ProfileService : IProfileService
{
	readonly IProfileRepository _repository;
	readonly ISession _session;
	public ProfileService(IProfileRepository repository, ISession session)
	{
		_session = session;
		_repository = repository;
	}

	public ProfileDto GetProfile(int id)
	{
		using(var trans = _session.BeginTransaction())
		{
			var result = _repository.FindById(id);
			return result;
		}
	}
}

Conclusion

In Part 1 we saw how to build off a previous example to enable an extendable IoC-enabled WCF Service solution. This gives us testable services without relying on Poor Man’s DI. In Part 2, we extended the library so we could have not only DI provided by StructureMap but to also leverage NHibernate’s extension points which help us achieve a Session/Call pattern. This solution involved several moving pieces, but in the end they fit together rather nicely and quite cohesively. As you play with the solution you may be surprised first to see that it actually works, but more importantly how much more time you’ll have to devote to the important stuff since you quit worrying about Data Access plumbing.

Posted in Uncategorized | 14 Comments »

Using StructureMap to Configure Applications and Components

Posted by coreycoogan on May 24, 2010

By now it’s probably a pretty safe assumption that any developer who’s worth their salt has at least heard of Inversion of Control (IoC) or Dependency Injection (DI), if not used it at least once. IoC as an architectural concept has many benefits, including testability and helping with Open/Closed Principle compliance. The specifics of DI have been discussed many times over, so consult your friendly neighborhood Google for more on the topic. What I’d like to talk about is the tooling that helps developers achieve IoC in their own systems. The tool is known as a Container and there are many good options to choose from in the .NET space. Top picks include Castle, StructureMap (SM), AutoFac, Ninject and even the very sad entry from Microsoft – Unity.

Why StructureMap?

I’ve had to use Unity at a current gig because it was approved and didn’t require .NET 3.5, but I’ll say right off that Unity is a very simple Container that lacks the features that make working with a Container fun. Granted, we’re using version 1.1, so I can’t speak to some of the enhancements found in 2.0.

I’ve blogged about Castle in the past, which I was using because it came standard in the S#arpArchitecture. Castle is a very good Container, but it has its downfalls. The biggest, in my opinion, is that its fluency is not very intuitive. Despite how many times I’ve used it, I can’t configure an application without looking at a previous example. It just doesn’t seem to flow and feels a bit clunky. It’s still a great tool, so I don’t want to take anything away from all the hard work that has gone into it.

Then there’s StructureMap. What can I say – SM rocks and I actually have fun using it. The fluent DSL flows easily and it is capable of doing everything I’ve ever really wanted it to. Some of my favorite, and most used features, include the default convention, the ease of adding custom conventions, registering open generics and showing what’s been configured. If you haven’t worked with it, have a look and play around with it. Like anything, it will take a bit to learn the ins and outs, but after that it’s pure joy. (NOTE: some of the doc I’m linking to is a bit out of date – the only downside to SM, however, there is plenty on CodeBetter)

Define Components

It is common practice to break different layers into separate components/assemblies/VisualStudio.Net Projects, such as Core, Data, Infrastructure, etc. It is also very common to have components shared throughout the enterprise, such as Inventory, SalesProcessing, Products, etc. This is what I’m referring to as components. Since each component may have its own unique DI requirements, configuring applications to initialize each of those components, as well as itself, can become challenging and when done incorrectly can make applications brittle.

Configuring the Application

The application, in the context of this post, refers to the actual executable – web site, Windows Form, WPF, Console, Windows Service, WCF. When using an IoC Container, the application should always have the responsibility of configuring and initializing the Container. It’s not uncommon to see some developers configuring a Container at the component level because that’s where the knowledge of the component’s dependencies exists. How would the application know about special conventions or nuances that the Container should be handling? The problem with this is the case where the application wants to leverage the Container and swap out one dependency for another.

Equally as painful is the practice of configuring all the components directly from the application. Once a developer gets everything working, the configuration is typically copied/pasted to other applications that use the same components. Now when something changes, someone has the joy of [hopefully] finding all the occurrences of the code in question and pasting a new version on top of it.

Configuring Components

So we don’t want the components to configure themselves in the Container and we don’t want to copy/paste the component configuration in all the consuming applications. How do we do it then? Well I’m glad you asked. The answer is found in StructureMap’s Registry facility.

A Registry in SM is a custom class, derived from the StructureMap.Configuration.DSL.Registry class. This is where the nuts and bolts of an SM configuration should exist. A component can have one or more registries, broken down into any sized unit that makes sense. Maybe the Inventory application has a registry for some common domain services and another for specific communication mechanisms that may vary depending on the type of application.

Here’s an example of a simple component Registry that has a couple specific needs and then relies on scanning and default conventions for the rest.


public class ProfileRegistry : Registry
{
	public ProfileRegistry()
	{
	    ForSingletonOf<IProfileValidator>()
		.Use<ProfileValidator>();

	    Scan(scanner =>
		     {
			 scanner.AssemblyContainingType<IProfileRepository>();

			 //use the default convention
			 scanner.WithDefaultConventions();

		     });
	}
}

Initializing the Application

Now that our components have their own default configurations broken into one or more Registry classes, we need to get that into our Container. As previously mentioned, it is the responsibility of the application to configure and initialize the Container. This is something we generally want to happen only once. This can be accomplished by putting the code to handle the initialization of SM, NHibernate, Logging, whatever, in a BootStrapper that gets called at the application’s entry point. This can be the Global.Application_Start in a web application or inside the Program class of a console or WinForm application.

Initializing Component Registries

So how does the BootStrapper initialize SM with each component registry? With StructureMap, there are actually three common techniques.

By Type

This technique is pretty straight forward and probably suits the majority of cases. In this example, we know what the Registries are and simply add them by type to SM’s configuration during initialization.


public static class Bootstrapper
{
	public static void Initialize()
	{

		ObjectFactory.Initialize(cfg =>
		{
		    cfg.AddRegistry<ProfileRegistry>();
		});

	}
}

By Instance

SM also offers the ability to add a registry to the SM configuration as an instance. This comes in very handy when you have a Registry that requires an instance of some type for its own configuration.

A real-life example of this is when using an NHibernate Session/Call pattern in a StructureMap enabled WCF service (details available in this post). In this case, I want the Wcf.NHibernate registry to tell SM how it should resolve an ISession. In order for this to happen, the Registry will need an initialized ISessionFactory instance, which will be passed to it by the application’s BootStrapper. Once the registry is instantiated, just add it to the SM’s configuration.


public static class Bootstrapper
{
	public static void Initialize()
	{
		ObjectFactory.Initialize(cfg =>
		{
		    cfg.AddRegistry<ProfileRegistry>();

			//get the sessionfactory from another method
		    ISessionFactory sessionFactory = InitFactory();

		    //create the WCF NH Registry
		    var nhWcfRegistry = new WcfNHibernateRegistry(sessionFactory);

			//add the Registry as an instance
		    cfg.AddRegistry(nhWcfRegistry);
		});
	}
}

By Scanning

Last but least, SM Registries can be added to the configuration via scanning. I really like SM’s ability to scan the types specified and apply common and custom conventions for type registration. I won’t go into details here, as the documentation is pretty good in this area.

During a scan, SM can be told to look for all Registry implementations and automatically add them to the configuration using the IAssemblyScanner.LookForRegistries() method. This can come in handy if you are scanning your components from your application. If you have a large number of components, it may be tempting to scan all the application’s assemblies and find registries, but be warned that this can make for a very long startup when you consider the number of types in your third party assemblies, like Log4Net, NHibernate, Castle, etc. Of course, you can always apply a convention to limit which components get scanned, but it’s definitely something to be aware of. Just put some thought into your use of IAssemblyScanner.AssembliesFromApplicationBaseDirectory() and IAssemblyScanner. AssembliesFromPath(path:string).


Scan(scanner =>
{
	 //include this
	scanner.TheCallingAssembly();

	//include the Data component
	scanner.AssemblyContainingType<IProfileRepository>();

	//include all the registries
	scanner.LookForRegistries();

});

Conclusion

Using Dependency Injection/IoC is a great way to build loosely coupled, composeable applications. An IoC Container is a tool that is used to tell your application how it should compose your types by defining the “what” and the “how” of your application’s dependency resolution. StructureMap is one of many available choices of IoC Containers for .NET, but its rich feature set and intuitive fluent DSL have put it at the top of my list.

Many examples and tutorials for StructureMap show how to configure a trivial application where all the types exist within the application or from application specific components. When dealing with components that are shared across the enterprise, it is important to give every consuming application a way to configure SM with their default configuration without copying the code into every application’s startup and without putting the configuration decisions solely in the hands of the component. This can be achieved through the use of the StructureMap Registry, which can be defined as coarse or granular as required at the co

Posted in Alt.Net, Architecture and Design, ASP.NET MVC, C#, IoC, NHibernate, StructureMap, TDD, Uncategorized | Tagged: , , , , , | 2 Comments »

Blogging with MS Live Writer

Posted by coreycoogan on November 9, 2009

A while ago, Microsoft released some pretty cool tools under the “Live” brand.  There are some pretty cool tools under this label that allow you to work with email/calendar, images and video and synch them to multiple services throughout the web.  The tool I’m blogging about now is Live Writer. I’m writing this post right now using Live Writer and am really enjoying the interface, which is much more fluid than the editor that comes from the browser.

According to the website:

“Writer makes it easy to share your photos and videos on almost any blog service—Windows Live, WordPress, Blogger, LiveJournal, TypePad, and many more.”

Live Writer is a desktop application that supports writing blogs with images, video and more.  I’m using WordPress (WP), which is a pretty awesome platform, and the integration is seamless and the Preview feature gives me a pretty good idea of what it will look like when published.  There’s even the ability to save your drafts to the blog server so you can edit it later from a different location.  In addition, there is a nice Plugin model where you can get and develop plugins to do all sorts of things.

Syntax Highlighting

Since this is a technical blog, the ability to copy/paste code snippets into my blog is very important. WP gives me a special tag for this (sourcecode lang=’csharp’).  When this tag is found, WP will automatically format my code using the SyntaxHighlighter found on Google Code.  I really like this highlighter’s ability to show line numbers, copy/paste functionality and the ability to view the source.  Unfortunately, I haven’t found any plugins that work equally as well for LiveWriter.

I did a little digging and found a simple method to allow me to get my desired syntax highlighting.  First, I found this answer on Superuser.com that shows how to stop LiveWriter from formatting special characters.  Next, I used this technique, in which you simple wrap your “sourcecode” tag in a <pre> and then all is well.  It’s a little bit of a hassle, but I think the trade off is worth it.  It wouldn’t take much to develop a plugin to do this, and there’s examples on the web for how to write one, but I’m content for now to just add the <pre> tag.

//sample code to show syntax highlighting
public void BlogThis(string blogPost)
{
	WordPress.PostBlog(blogPost);
	this.Observers.Notify(blogPost);
}

Posted in Blogging, Uncategorized | Tagged: , , | Leave a Comment »

Castle Windsor Tutorial in Asp.Net MVC

Posted by coreycoogan on November 6, 2009

Castle Windsor is one of the more popular IoC containers in the .NET space today.  Others include StructureMap, NJect, AutoFac, Unity and others.  My top choices are StructureMap and Castle, but I’ve never really used NJect or AutoFac and it’s my opinion that Unity is the weakest of them all and hardly worth mentioning.  I’ll show some of the basics of Castle Windsor – enough to get you setup in your ASP.NET MVC, or any other .NET application. I’ll show you enough to handle 90%+ of the most common IoC needs. Much of my examples come from the S#arp Architecture, which I’m using in my current project.

Castle Windsor Configuration Options

Windsor offers 2 configuration options – .config file or code.  Like many others, I have moved away from trying to do everything in my .config file and do more in code, practicing Convention or Configuration (CoC).  Because the novelty of .config files is so early 2000′s, I’ll focus on configuring Castle using good ‘ole C# and some conventions I follow in my applications.

Common Conventions

Nothing ground breaking here, but I like to keep my controllers as light as possible.  Therefore, I keep my application logic in an application service layer.  My app services have one ore more repositories injected into them where domain objects can be retrieved for performing operations.  My repositories, application services and interfaces all reside in different layers, which in my case is a physical assembly.  Some folks prefer to inject repositories directly into the controller, which works as well, but using services works better for me because I feel I get better separation and it simplifies the controller’s constructor, which is how I handle dependency injection.

So here’s the breakdown of my layers (assemblies/projects):

Application Layer:
Application Services, Application Service Interfaces

Data Layer:
Repository Implementations

Domain Layer (Core):
Repository Interfaces

UI Layer:
Controllers

Configuring Castle to Handle My Conventions

All of my dependency injection is through the object’s constructor.  As long as Windsor can resolve all the dependencies required by the constructors, it will be able to create and resolve the dependent objects as well.  IoC configuration is typically left to the application (MVC, WinForms, WPF, etc.), so you would bootstrap the configuration in some sort of Application Start event, which in the case of ASP.NET is available from the Global.asax.  All the code you’re about to see will exist in a class responsible for the IoC configuration that gets called from my Application_Start event.

First, a sample of a repository class and its interface, then how to automatically register all repositories in one swoop.


//my repository class from the Data assembly
namespace S2sol.Rpo.Data
{
     public class ClassroomRepository : S2sol.Rpo.Core.DataInterfaces.IClassroomRepository
    {
    }
}

//my Repository interface from the Core assembly
namespace S2sol.Rpo.Core.DataInterfaces
{
    public interface IClassroomRepository
    {
    }
}

//this is how I would resolve an IClassroomRepository to its implementation from Castle
IClassroomRepository repo = container.Resolve<IClassroomrepository>();

To make things simple, I’ll use Castle’s AllTypes.Pick() method, which effectively scans the types in an assembly. In my example below, I’m scanning my Data assembly and looking for non-generic interfaces that are the first interface defined on the classes in my Core assembly and register them with the container.

private static void AddRepositoriesTo(IWindsorContainer container)
{
    container.Register(
    AllTypes.Pick()
    .FromAssembly(typeof(UserRepository).Assembly) //get the assembly where this repository lives
    .WithService.FirstNonGenericCoreInterface("S2sol.Rpo.Core") //look for interfaces from this assembly
    );
}

I’m going to want to automatically register all my Application Services as well so they can be injected into my controllers. This syntax is a little simpler because those interfaces and implementations are in the same assembly.

private static void AddApplicationServicesTo(IWindsorContainer container)
{
      container.Register(
        AllTypes.Pick()
        .FromAssembly(typeof(ProfileService).Assembly)
        .WithService.FirstInterface());
}

Now I’ll want to make sure that all my controllers are registered. This done by using the RegisterControllers extension method from the MvcContrib.Castle library.

private static void AddControllersTo(IWindsorContainer container)
{
	container.RegisterControllers(typeof(HomeController).Assembly);
}

Now all that’s left is to show the simple part, and that’s how to register any one-offs that may not fit into your conventions. For example, I have an IValidator interface that I want to resolve to the Validator implementation I’m using in this project.

container.AddComponent<IValidator,Validator>();

It’s as simple as that. Once this has been put in place, I can just continue to develop repositories, application services, controllers and their respective interfaces and never have to remember to register any of them as long as I follow my conventions.

Castle’s Factory Facility

Facilities are how Castle handles extensibility. These are plugins for Castle that can be used for just about anything. Some of the more popular ones support NHibernate, WCF and logging. The one that comes in handy for my needs is the FactorySupportFacility. This facility allows me to configure a factory method in the container and control how objects get resolved.

The RoomParentsOnline MVC application makes use of a custom IPrincipal object that gets injected into my UserSession class, along with an HttpSessionStateBase implementation. The UserSession class is used for interacting with the current user, and by passing it an IPrincipal and HttpSessionStateBase, I have a testable design that I can develop using TDD.

//constructor for the UserSession implementation
public UserSession(IProfileService profileSerivce,
            HttpSessionStateBase session, IPrincipal principal)

The first thing to do is make sure that Castle knows about the Factory Facility that I wish to use. To do this, you can either register the facility in the .config file or in code. I’ll show you how to add it in code. This would be done in your registrar class’s constructor to make sure it’s available right away.

container.AddFacility<FactorySupportFacility>();

Now that Castle knows I’m using the Factory facility, I can tell it how I want to resolve the IPrincipal and HttpSessionStateBase. I also have to tell it how to resolve an IIdentity because of the way my code is accessing it (for testability). In the code below, I am telling Windsor to keep the registered objects available during the scope of a request. I then pass it the Function expression for how to create the object, which is all coming from the HttpContext.

private static void AddSecurityConcernsTo(IWindsorContainer container)
{
	container.Register(Component.For<IIdentity>()
	  .LifeStyle.PerWebRequest
	  .UsingFactoryMethod(() => HttpContext.Current.User.Identity));

	container.Register(Component.For<IPrincipal>()
	  .LifeStyle.PerWebRequest
	  .UsingFactoryMethod(() => HttpContext.Current.User));
	
	container.Register(Component.For<HttpSessionStateBase>()
		.LifeStyle.PerWebRequest
		.UsingFactoryMethod(() => new HttpSessionStateWrapper(HttpContext.Current.Session)));


}

I’m sure you’ll agree that this code makes it very simple to invert some of those pesky dependencies that come from the core ASP.NET plumbing. This technique is very effective for designing testable classes that need to interact with some of the “ugly stuff”.

The MvcContrib WindsorControllerFactory

Now that we have our Windsor container all configured to resolve our controllers, why not let the MVC framework use that container for creating our controllers. This can be done quite easily using the WindsorControllerFactory from the MvcContrib project. This is an implementation of ASP.NET MVC’s IControllerFactory interface. Using it is simple – just create an instance and give it your container and then register the factory with MVC. This is something that needs to be done during Application_Start.

ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));

Common Service Locator

The last thing that I’ll mention is the CommonServiceLocator project. If you already have your IoC configured, you might as well make it available to all your code that may need to get object implementations without dependency injection. The CommonServiceLocator makes this easy by adapting all the major IoC containers to work under a common interface with a few key static methods. This is something that should also happen in the Application_Start.

ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));

Bringing it all Together

Now I’ll just put everything together for your copy/paste pleasure.

Global.asax

protected void Application_Start()
{
	InitializeServiceLocator();

	//do everything else here
}

/// <summary>
/// Instantiate the container and add all Controllers that derive from 
/// WindsorController to the container.  Also associate the Controller 
/// with the WindsorContainer ControllerFactory.
/// </summary>
protected virtual void InitializeServiceLocator()
{
	//create the container
	IWindsorContainer container = new WindsorContainer();
	//set the controller factory
	ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
	//configure the container
	ComponentRegistrar.AddComponentsTo(container);
	//setup the common service locator
	ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
}

ComponentRegistrar.cs

public class ComponentRegistrar
    {
        public static void AddComponentsTo(IWindsorContainer container)
        {
            container.AddFacility<FactorySupportFacility>();

            AddControllersTo(container);
            AddGenericRepositoriesTo(container);
            AddCustomRepositoriesTo(container);
            AddApplicationServicesTo(container);
            AddOneOffs(container);
            AddSecurityConcernsTo(container);
        }

		//add all my controllers
        private static void AddControllersTo(IWindsorContainer container)
        {
            container.RegisterControllers(typeof(HomeController).Assembly);
        }

		//handle any one off registrations that aren't convention based
        private static void AddOneOffs(IWindsorContainer container)
        {
            container.AddComponent<SharpArch.Core.CommonValidator.IValidator,Validator>("validator");
        }

       //handle registrations for my security classes
        private static void AddSecurityConcernsTo(IWindsorContainer container)
        {
            container.Register(Component.For<IIdentity>()
              .LifeStyle.PerWebRequest
              .UsingFactoryMethod(() => HttpContext.Current.User.Identity));

            container.Register(Component.For<IPrincipal>()
              .LifeStyle.PerWebRequest
              .UsingFactoryMethod(() => HttpContext.Current.User));
            
            container.Register(Component.For<HttpSessionStateBase>()
                .LifeStyle.PerWebRequest
                .UsingFactoryMethod(() => new HttpSessionStateWrapper(HttpContext.Current.Session)));


        }


		//register my application services
        private static void AddApplicationServicesTo(IWindsorContainer container)
        {
            container.Register(
                AllTypes.Pick()
                .FromAssembly(typeof(ProfileService).Assembly)
                .WithService.FirstInterface());
        }
		
		//register all custom repositories (not generic)
        private static void AddCustomRepositoriesTo(IWindsorContainer container)
        {
            container.Register(
                AllTypes.Pick()
                .FromAssembly(typeof(UserRepository).Assembly)
                .WithService.FirstNonGenericCoreInterface("S2sol.Rpo.Core"));
        }

		//register all my SharpArch generic repos
        private static void AddGenericRepositoriesTo(IWindsorContainer container)
        {
            container.AddComponent("entityDuplicateChecker",
                typeof(IEntityDuplicateChecker), typeof(EntityDuplicateChecker));
            container.AddComponent("repositoryType",
                typeof(IRepository<>), typeof(Repository<>));
            container.AddComponent("nhibernateRepositoryType",
                typeof(INHibernateRepository<>), typeof(NHibernateRepository<>));
            container.AddComponent("repositoryWithTypedId",
                typeof(IRepositoryWithTypedId<,>), typeof(RepositoryWithTypedId<,>));
            container.AddComponent("nhibernateRepositoryWithTypedId",
                typeof(INHibernateRepositoryWithTypedId<,>), typeof(NHibernateRepositoryWithTypedId<,>));

        }
    }

Conclusion

This post ended up being longer than I originally intended, but hopefully you gleaned some nice little gems here. Castle Windsor is really easy to setup and use and there are many contributions out there that add more great functionality. Sometimes it’s hard to know how to use these types of tools without some concrete examples and I hope to have you shown you some useful ones here.

Posted in Alt.Net, Architecture and Design, ASP.NET, ASP.NET MVC, Design Patterns, IoC, Uncategorized | Tagged: , , , , , , , , , , , , , | 23 Comments »

 
Follow

Get every new post delivered to your Inbox.