Thursday, January 29, 2009

More Swiz features, or Swiz 0.0.5 Part 2!

Since my last post was getting a bit long, I said I would get a second installment out 'soon'. It took slightly longer than I hoped to get together, but it gave me a chance to put more into Swiz, that I can also blog about 'soon'!. I left you hanging a bit after mentioning Swiz's new Prototype bean, so lets get right down to business. If you've used Spring or ColdSpring before, you should be well aware that they manage both singleton and non-singleton beans. Spring 1.0 and ColdSpring provide a 'singleton' attribute for the element in your config file. The singleton attribute defaults to true, meaning there will only ever be one instance of that bean in the factory's cache, but if you change it to false, the bean definition becomes a prototype for a new instance that is created every time getBean is called. In Spring 2, the semantic was shifted a bit, and now the attribute is called 'scope', setting it to 'prototype' is the same as singleton=false. I like the shift in terminology, it's more expressive of what Spring is actually doing.

Handling prototypes, or non singletons, is pretty much a core function of an IoC container, but Swiz has a little secret, we've been getting by without it. This has a lot to do with the route I initially followed to build Swiz. Being that Flex already has a built in xml language which you use to define object instances, it seemed very natural to me to leverage MXML for Swiz's configuration. However, when you supply objects to Swiz in a BeanLoader, you are defining instances, which are cached as singletons. Even though this is extremely simple, and I could easily argue the point that 90% of all objects managed by IoC frameworks are in fact singletons, there is also plenty of reasons why you man need a unique instance every time a bean is retrieved from Swiz. For instance, what if you wanted to wire up a separate instance of a controller for each view in a tab navigator. Well, with Swiz's new Prototype bean, you can! Here's an example of the new Prototype bean in action:

<?xml version="1.0" encoding="utf-8"?>
<BeanLoader xmlns="org.swizframework.util.*"
                xmlns:mx="http://www.adobe.com/2006/mxml"
                xmlns:swizframework="org.swizframework.*"
                xmlns:delegates="foo.delegates.*"
                xmlns:factory="org.swizframework.factory.*">

    <!-- hello service -->
    <mx:RemoteObject id="widgetService" destination="widgetService"/>

    <!-- delegate for the hello controller -->
    <delegates:WidgetDelegate id="widgetDelegate"/>

    <factory:Prototype id="widgetController"
                className="foo.controllers.WidgetController"/>

</BeanLoader>

I've defined three objects, a delegate, a remote object, and a controller, if you've worked with Swiz in the past you can already guess how they are being wired together. However, instead of defining the controller directly in MXML, I have defined a Prototype bean, providing an id and className. This should look very familiar to users of Spring and ColdSpring, there's just one big difference to take note of. In Swiz, a prototype is by default non-singleton. You will always get a new instance anytime this widgetController is injected into a view or another bean. It's important to take note of this difference. Your normal beans are always singletons. Prototypes are by default definitions of non-sigletons. Which makes a whole lot of sense semantically. However, if you would like you, can alternately use Prototype to define singletons, by setting the attribute singleton="true". As a matter of fact, if you took this route, your BeanLoaders would look a whole lot like your Spring or ColdSpring config files! I hope you find some great uses for the new Prototype, and check back for the next installment, Swiz's new IInitializingBean interface!

Good to end on another cliffhanger, right?

Monday, January 26, 2009

A bunch of sci-fi movies I can't wait to watch with my kids

Spurred on by a tweet by Ray Camden, I decided to put together a list of sci-fi / fantasy movies I can't wait to watch with my kids when they get old enough, as well as some great ones I have watched with them recently. They are 5 and 7, so no, we're not watching Alien! So, here's the 'waiting' list:

1. Blade Runner (probably my all time favorite movie)
2. 5th Element
3. 12 Monkeys
4. Legend
5. Dark City
6. 2001
7,8,9. All three LOTR's.
10. Planet of the Apes
11. Alien(s)
12. Pan's Labyrinth (maybe, it's pretty scary but it's on the appletv)

And the ones my wife has deemed 'acceptable'. Ok, some are a stretch in the genre...

1. Narnia
2. The Dark Crystal
3. The Goonies
4. Wall-e
4. Harry Potter 1,2 & 3. We decided 4 and 5 are too heavy
5. All 4 Indiana Jones
6. Of course all Star Wars, we watch the damn Clone Wars cartoon every freaking Saturday. God it SUCKS!
7. skinnyarms comment reminded me, we watched Tron recently. My kids really liked it, but were awfully confused by the 1980s concept of computers. Simon kept looking at my funny, and I know he was thinking, "you don't really make crazy stuff like that at work"!

Honorable non-sci-fi mention. We just watched The Wiz, that was very funny to watch with them!

So, what are you watching with yours?

Tuesday, January 06, 2009

New Swiz 0.0.5 for the New Year!

Update: Just wanted to clear up a few typos. You need to call setStrict(true) before calling loadBeans([Beans]). The code snippet has been fixed. Also, I misspoke, Sönke's strict flag only supports fully qualified class names or static constants in the format SOME_EVENT (all caps with underscores). I have also made that change.

Happy New Year all! You may have noticed I've been on a bit of a blogging holiday, but after a productive for Christmas/new years, I've released a new build of Swiz over at our googlecode site! I was hoping to make a release earlier this week, but decided to take a little extra time to restructure the repository so I could include dependencies and project files to make it easier to build Swiz from source. So what's in this shiny new build? We've got two major features, and a bunch of bug fixes, which I'll list out at the end of the post. Most importantly though is run-time checking of event types for DynamicMediators, which we are supporting through two different approaches. It really only takes one or two times scratching your head over some non functioning code, only to find a misspelled event type, to see the need for run-time checking of event types. The first approach has been added by a new addition to the Swiz team Sönke Rohde. Sönke's been very active on the google groups list, as well as blogging some great articles on Swiz and talking with me quite a bit off list about Swiz enhancements. I've very happy to have him now contributing! But let's get on to this run time event checking...

If you've read the documentation for DynamicMediator, you know that Swiz looks for the Mediate annotation to essentially create a wrapper for a function to be added as an event listener for any event type. The syntax looks like the following:

[Mediate(event="user:SaveUserEvent", properties="user")]
public function saveUser(user : User) : void { ... }

Swiz will not only look for Mediate annotations in objects in your BeanLoaders, but also in any view it sees added to the stage. It then creates a DynamicMediator for the event type supplied, which passes the event properties listed into the function you have annotated. DynamicMediators can significantly reduce boilerplate code, but do have one major drawback. You can only supply string values in Flex medatada tags. It would be great to be able to write:

[Mediate(event=com.foo.SaveUserEvent.SAVE_EVENT, properties="user")]

and have the Flex compiler understand that you are referring to a property of a class, but unfortunately, it won't. However, Sönke has added a 'strict' flag, which will force Swiz to evaluate the string value of the event type as a fully qualified class name or static constant in that class, and throw an error if the class cannot be found. This will occur as soon as Swiz tried to create the DynamicMediator, effectively giving you runtime checking of your event types. In order to use this in your project, you would change your initialization of Swiz to something like the following, in an event handler for preinitialize:

private function onInitialize() : void {
    Swiz.setStrict(true).loadBeans( [ Beans ] );
}

You may have noticed the method chaining style I used, which is another new change. Static configuration methods on Swiz return the Swiz instance, allowing you to chain method calls. Now if we change the mediate annotation above to:

[Mediate(event="com.foo.SaveUserEvent.SAVE_EVENT", properties="user")]
public function saveUser(user : User) : void { ... }

Swiz will first check to make sure that a class named com.foo.SaveUserEvent exists, and has a string property called SAVE_EVENT when it attempts to create the DymanicMediator. Early on, Sönke had told me that he commonly uses a standard in his development of always using fully qualified class names as his event types, so an Event class com.foo.SaveUserEvent would use a call to super("com.foo.SaveUserEvent") in it's constructor. In that case, you could use an annotation such as the following:

[Mediate(event="com.foo.SaveUserEvent", properties="user")]
public function saveUser(user : User) : void { ... }

and Swiz would just make sure the class existed. However, this would enforce that you MUST have a class for every event type, excluding DynamicEvents. By adding adding the ability to resolve a static constant, you can place your event types in any class. Let's say you had a com.foo.EventConsants class, you could use:

[Mediate(event="com.foo.EventConsants.SAVE_USER_EVENT", properties="user")]

for your mediator, and then dispatch a DynamicEvent like this:

var e : DynamicEvent = new DynamicEvent(EventConsants.SAVE_USER_EVENT);
e.user = currentUser;
Swiz.dispatchEvent( e );

I really like the flexibility of this approach. However, while Sönke was working on his strict checking approach, I was working on a similar solution to the same problem. While attending a Spring User Group meeting, I saw that they were experiencing similar issues with their move to annotation driven configuration, and was very intrigued by their 'expression language'. So I have come up with a simple implementation of my own, which I think will continue show it's use in Swiz elsewhere as time goes on.

Let's take a look at how you might use the new expression language instead of the strict approach. In my own work, I have gotten into the practice of storing event types in my controllers, for me it's a way of keeping them part of a particular domain. So in the previous example, if I have a UserController with a SAVE_USER_EVENT property, I would reference it directly in my SaveUserEvent type, calling super(UserController.SAVE_USER_EVENT) in the constructor. Since I have added my UserController to BeanLoader, with an id of "userController", I can now use an expression in my Mediator to reference the SAVE_USER_EVENT property, like so:

[Mediate(event="${userController.SAVE_USER_EVENT}", properties="user")]

When Swiz encounters the ant-style syntax I chose for expressions, it evaluates it in the format [beanId].[property]. If a bean with the supplied ID does not exist, you will immediately get a runtime ExpressionError. What's nice about this format is, you can use public static constants or instance variables for your event types,, and you can even nest them! In the earlier example using Sönke's strict flag, I mentioned using a class called EventConstants for event types. Depending on your development style, you could either provide this bean to Swiz and reference it directly in you expression, like I did with the userController, or maybe your controllers could have an instance of it, in an 'eventTypes' property. Then you can use an expression like:

[Mediate(event="${userController.eventTypes.SAVE_USER_EVENT}", properties="user")]

I think that both these styles will be a great improvement for developers using Swiz, providing a flexible model to suit your development standards. Unless I have strong community outcry to adopt one format over the other, I see no reason not to support both. Well, this post has already gotten a bit long in the tooth, so maybe I'll leave this as part one, and let you know that part two will cover, Swiz's new Prototype bean! So go download the new Swiz 0.0.5 library and happy coding!

Changes / Fixes for Swiz 0.0.5:

- DynamicChannelSet now contains an 'endPointName' property that can be set to 'flex2gateway' for ColdFusion
- Multiple calls to autowire for an object or view will only create mediators once
- handleAutowireEvent ignores flash.* and mx.* classes
- DynamicMediators allow event properties to be null
- Primitive objects can be added to BeanLoaders
- Autowire now supports by type (with [Autowire] instead of [Autowire(bean="foo")])
- DynamicResponder supports passing an array of values to be passed back into the result handler
* for example to have the original saved object passed in to a save result function
- Refactored all bean factory specific functionality out of Swiz and into BeanFactory
- Added Strict flag and MediatorUtils for event type checking
- Added ExpressionUtils, also or event type checking
- Added Prototype object, for non-singleton bean definitions

Labels: , ,