agile web development with the castle project 15/05/2008, skills matter gojko adzic [email protected]
TRANSCRIPT
Agile Web Development with the Castle Project
15/05/2008, Skills MatterGojko Adzic
[email protected]://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