350 likes | 389 Views
Agile Web Development with the Castle Project. 15/05/2008, Skills Matter Gojko Adzic gojko@gojko.com http://gojko.net. Why should you care?. Increases programmer productivity Allows us to apply modern programming practices (AoP, DI) Provides a solid foundation for agile web programming
E N D
Agile Web Development with the Castle Project 15/05/2008, Skills Matter Gojko Adzic gojko@gojko.com http://gojko.net
Why should you care? • Increases programmer productivity • Allows us to apply modern programming practices (AoP, DI) • Provides a solid foundation for agile web programming • Brings best ideas from Spring/Java and Ruby on Rails to the .NET world
What is it? • Several loosely-coupled components • Windsor IoC and AOP container • ActiveRecord data-access • Monorail MVC • Bunch of other libraries (Dynamic Proxy…) • You can use them separately • Even more productive when used together
But it is a RC! • A bad marketing decision • RC because it is work in progress, not because it is unstable • I’ve used it in production for about two years now, no problems at all
Application framework • Mix between Spring and RoR • Integrates with almost anything • Lightweight, short learning curve • Convention over configuration • Lots of helpers and utils • Nothing is enforced
What do we get? • Very efficient programming model • Almost all the plumbing is already there • Testable web apps (everything below the UI) • Will age gracefully
What do we lose? • ASP.NET components • MS stamp of approval • “this is not .NET” attitude might be a problem • Need more training, probably cannot hire people off the street
ActiveRecord • Simple O/R • Class=table • Object=row • Property=column value • Configuration by code attributes • Uses NHibernate under the hood
ActiveRecord (+) • Incredibly simple O/R mapper • Simplifies NHibernate configuration for common cases • Unit-testable • Supports validation • Great integration with MVC engine
ActiveRecord (-) • Bad separation of concerns • It represents domain code • It also dictates storage • Generally better for green-field development
Key stuff to remember for AR • the class needs to be annotated with attributes • create a dedicated assembly for ActiveRecord types • beware of using names that are DB keywords • use ActiveRecordValidationBase if you want validations to work
Key stuff about AR testing • Kill the initialisation flag in unit tests to allow re-initialisation • ActiveRecord can generate the schema for you, but this is not perfect • Don’t forget to flush • Try to reload objects and verify properties
You don’t have to use AR! • Castle integrates with NHibernate and IBatis nicely • Data mapping and validation works on plain CLR objects • A bit more code, but much more flexibility
Monorail • MVC based on Rails • Smart url mapping • Class=folder part of the URL • Method=file part of the URL • Takes care of all HTTP plumbing • Flexible view engines
Monorail: Controllers • Basic building blocks of Monorail • Responsible for workflow and session • Group related workflow steps • SmartDispatcherController binds GET/POST variables to method arguments • No formatting!
Monorail: Actions • Perform a single step in the workflow • Prepare data for the view (PropertyBag) • (optionally) Select the view • Chaining/Reuse patterns • Call method • RenderView • RedirectToAction • Use Flash to pass messages while redirecting
Monorail: Views • Data formatting • Simple scripting, related to UI Formatting • No business code, no workflow code
5-minute Velocity guide • $varname (or ${varname.property}) • #if / #end • #parse to include other scripts • Partial templates with #foreach
Monorail: Helpers • Utilities for formatting • Generating UI code • Forms • Ajax (prototype, js proxies) • Or roll your own
Monorail: Layouts • “Master pages” or templates • Use $childContent to embed views • Use $siteRoot for relative paths • Set by attribute on class or method
Monorail: Components • Reusable parts of the layout • Menu bars • Shared functional parts • Alternatives • Use Helpers for formatting • Use partial templates and loops for repeatable content • Can also be done with Ajax DIVs
Monorail: Filters • Actions to execute before or after controller actions • Simple web AOP • Authorisation • Logging
Monorail: Rescues • View called on error • Specify on whole controller or on action • Generic or bound to an exception • Individual actions do not have to worry about error handling in most cases -> less code
Monorail and ActiveRecord • Extend ARSmartDispatcherController • Data-mapping to load record objects: • ARFetch • ARDataBind • Scaffolding • Not the cleanest solution – storage and business logic mixed – but very productive
Monorail Unit Testing • Use BaseControllerTest from Castle.MonoRail.TestSupport • Call InitController to prepare the environment • Test the class like any other • Inject services into containers so that you can test them in isolation
Monorail (+) • HTTP Request plumbing • Smart dispatching, data binding • Convention over configuration • Unit testing • Fantastic AR integration • Several layout engines
Monorail (-) • Attribute based layout and area selection • Hashmap for view properties • I have mixed feelings about this • Windsor integration a bit too complicated • Maybe use service locator pattern in this case
Key stuff to remember (MR) • Override the web app to initialise AR • Use data-binding to load whole objects • Put stuff into PropertyBag to pass to a view • layouts are page templates • Use the Flash to simplify workflow • Learn standard helpers and use them
Windsor/MicroKernel • MicroKernel is an IoC/AOP framework • Windsor loads configuration from files • Manage component pooling and lifestyles • Provide interception
Windsor: Components • Components are application building blocks • They can provide a service • Constructor arguments and properties can be automatically resolved • Constructor args are mandatory • Properties are optional • Lazy Loaded!
Windsor: Facilities • Extend the framework by hooking to component events • Attaching interceptors • Integrating with 3rd party libraries • Standard Facilities • Automatic transaction management • Logging • Starting/stopping components
Windsor+Monorail • Inject services into controllers • Add IContainerAccessor to web app, initialise ONE Windsor context on start • Makes controller code even more simple, but complicates configuration • Alternative is to use service locator
Windsor: Key stuff to remember • Services are automatically resolved by interface • Components are lazy loaded • Initialise only one context per application • Beware of cyclic dependencies • Use Features and Interceptors for AOP
Why I like Castle • Makes simple things very easy, but allows doing complex stuff as well • Co-operates with other popular libraries • Convention over configuration • AR+MR Great for prototyping • Allows us to cover big parts of web code with unit tests
Where next? • ALT.NET beer meeting – straight away • 21/05 MS MVC@DNUG http://dnug.org.uk/ • www.castleproject.org • EvilLink demo app: http://gojko.net