Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Bricks and Mortar: Building a Castle : Page 5

Discover how to use the Castle Windsor Inversion of Control container to build flexible applications.


advertisement

Open Generic Types

Windsor supports registration and resolution of open generic types. An open generic type is a generic class without its type arguments specified. For example, if you have a Repository<T> class, then Repository<Invoice> is a closed generic type because T is specified as Invoice, whereas Repository<> is an open generic type because T is left unspecified.

You can register closed generic types just as you would any other dependency:



container.Register(   Component.For<IRepository<Invoice>>() .ImplementedBy<Repository<Invoice>>()   );

You could then retrieve this component like this:

var repo = IoC.Resolve<IRepository<Invoice>>();

However, the following would fail because you had not registered a Repository<Customer>:

var repo = IoC.Resolve<IRepository<Customer>>();

Instead of explicitly registering each closed generic type that you want to use, you can instead register the open generic type:

container.Register(   Component.For(typeof(IRepository<>)) .ImplementedBy(typeof(Repository<>)) );

You can now ask the container for IRepository<Invoice>, IRepository<Customer>, IRepository<KitchenSink>, etc. Windsor creates closed generic types on the fly from the open generic type registration!

Notice the slightly different syntax in the call to Component.For(), which passed typeof(IRepository<>). The reason is that generic type arguments (the stuff in angle brackets) in C# accept only closed generic types. If you want to specify an open generic type, you need to use the typeof() syntax.

Author's Note: When you're using Convention-over-Configuration via AllTypes, open generic types are located and registered automatically without you having to worry about the details. This is yet another reason to prefer Convention-over-Configuration where possible.

Testing Windsor Configuration

You should have integration tests around your components to provide confidence that the container is configured correctly. However, it is often useful to have a smoke test to quickly verify your container configuration. If you have an IWindsorContainer, you can walk through all registered components and ask the container to resolve (and thus create, with all its dependencies) each one:

foreach(var handler in container.Kernel .GetAssignableHandlers(typeof(object))) { var impl = handler.ComponentModel.Implementation;   if(impl.IsAbstract || impl.IsGenericTypeDefinition) {     continue;   } container.Resolve(handler.Service); }

Notice that you ignore abstract and open generic types. Abstract types, by their very definition, cannot be created. Open generic types could be resolved if you supplied appropriate generic constraints, but unless you're using many open generic types, it is often easier to skip them and add additional logic to explicitly resolve them with an appropriate type parameter, such as an explicit call to container.Resolve<IRepository<Invoice>>(). You might also want to skip over Presenters or similar components that require external dependencies and write Presenter-specific smoke tests yourself. Still, the simple test above will verify the registrations of the majority of your components.

I hope that you have found this brief tour of Castle Windsor informative and have a better understanding of how you can use it for dependency registration and resolution. IoC containers such as Windsor provide a solid foundation for keeping your application architecture flexible and robust in the face of ever-changing requirements.



James Kovacs is an independent architect, developer, trainer, and jack-of-all-trades who specializes in Agile development using the .NET Framework. He is passionate about helping developers create flexible software using test-driven development (TDD), unit testing, object-relational mapping, dependency injection, refactoring, continuous integration, and related techniques. James is a proud member of CodeBetter.com, a Microsoft Most Valuable Professional (MVP) Solutions Architect, and a card-carrying member of ALT.NET, a group of software professionals continually looking for more effective ways to develop applications. He received his Masters degree from Harvard University.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date