in

Nikola Malovic

.NET development and architecture
VusCode - Coding dreams since 1998

Add to Google Reader or Homepage Add to Pageflakes Subscribe in NewsGator Online Subscribe in Bloglines Add to Technorati Favorites View Nikola Malovic's profile on LinkedIn

VusCode - Coding dreams since 1998!

.NET exploration, articles, cool links, surf logs, book reviews, .net, c#, smart clients, software factories, patterns & practices, web casts and much more
  • Model View Presenter (MVP) – Tips from trenches (TFT) – Working with HttpContext (Part 2)

    Intro

    This is part 2 of blog post series where I am presenting solutions I came up with to some common problems developers are facing implementing the MVP pattern in real world applications.

    Previously on tips from trenches:

    Today’s hurdle: Using HttpContext without System.Web

    (Source code used in today’s example can be downloaded from here)

    One of the principles I really feel strong about it is not allowing at all referencing of System.Web assembly by Presenter.

    Main reason why I feel so is based on the fact that referencing assembly allows to developers in your team to use types from that assembly (HttpContext, Session, Query, Cache etc) which effectively makes testing of Presenter code much harder and negates completely rationale of using of MVP  design pattern.

    Here’s very simple example I’ll use in today’s post:

    Imagine you have a presenter which based on value of some query parameter is performing some redirecting or updating UI elements.

    The easiest way reference the System.Web into my presenter implementation of that code will be trivial but testing that code will require things like creating fake web context which IMHO is perfect sign of one of most important web test smells.

    Luckily, there is solution :)

    Model View Presenter pattern combined with Adapter design pattern offers easy and effective way of tackling this problem and this post is about to show how to do that.

    Adapter design pattern

    This pattern is one of patterns I recently rediscovered as maybe one of the most useful patterns in every day programing. The pattern itself is not very sexy, because it is very simple. It’s purpose is to handle the cases Adapter_realexamplewhenever we need to adapt the interface of one component to the interface we need.

    Canonical example mostly used in explaining the pattern is the case of US and European power adapters. I am sure I am not the only one European who found himself shocked by the fact that power outlets in USA are totally different then the European one. In other words, European power sockets are wider and round while US are narrow and flat. Luckily, there’s Ebay where one can buy himself an adapter compatible with USA power outlets with entry holes compatible to European standards. That’s how you charge your laptop using original cable adapted to custom power outlet.

    Adapter design pattern is exactly the same thing.

    As we can see on above diagram, when client calls a Target object he would get instance of Adapter inheriting from Target which will delegate to SpecificRequest method of of Adaptee object all of the calls for Request() method (Adaptee object is containing instance of Adapter).
    In other words, Adapter “implements via delegation” to Adaptee.

    Building the TDD friendly HttpContext

    Implementation of TDD friendly HttpContext will be based on couple of steps:

    • building System.Web agnostic interface which would:
      • perform the role of Facade by hiding most of the the members not important for MVP
      • perform a role of a service contract which would be used by IoC container where custom HttpContext service will be need
    • building special collection type which would enable us transparent intercepting interface members access
    • building HttpContext service adapter which would implement the interface by delegating all of the calls to interface members to System.Web.HttpContext
    • registering service into IoC container

    Defining IHttpContextService

    As previously mentioned, first step in implementing the TDD friendly http context is defining the feature list I am expecting to use in my Presenters. Based on some of my current experiences, that interface might look like this:

    image

    You can see from the interface definition to the left that (IMHO) important http context members are:

    • Redirect(url) method – When presenter and\or controller are responsible for driving navigation (more about controller in upcoming post)
    • QueryString property – read only name-value collection property which contains collection of string pairs representing url parameter name and value
    • User property  - IPrincipal type doesn’t require usage of System.Web and defines a lot of useful things for implementing presenters
    • ContextItems  - read only property of custom name value collection type (more about that in second) which contains collection of string pairs representing name of httpcontext item and value that item carries
    • Session – read only property of custom collection type containing string pairs representing application session variable entries

    Key point here is that none of the members is not returning types from System.Web and that there are no Response, Request etc members. Only a small subset of really needed things defined in “easy to mock” way.

    One thing Web Client Software Factory failed

    While we speak about interface definition I would like to mention here a thing I’ve been disappointed seeing how it is been implemented there.

    WCSF has IHttpContextLocatorService implemented like this (taken from reflector)

    public interface IHttpContextLocatorService
    {
        // Methods
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        IHttpContext GetCurrentContext();
    }

    and that IHttpContext interface look like this (part of)

    public interface IHttpContext
    {
        // Methods
        HttpApplicationState Application { get; }
        HttpApplication ApplicationInstance { get; set; }
        Cache Cache { get; }
        HttpContext Context { get; }
        ProfileBase Profile { get; }
        HttpRequest Request { get; }
        HttpResponse Response { get; }
    }

    As you can see by the fact that interface has members of types defined in System.Web, in order to use IHttpContextLocatorService I am still required to use System.Web. In other words, to get url query parameter I would still have to use System.Web.HttpRequest.

    I might be missing something pretty big here, but IMHO there is no sense at all in how P&P team implemented this service. Testing pain I felt using WCSF related to this made me thinking about better solutions and this post is result of that :)

    HookableNameValueCollection

    Now when you saw interface definition and heard where from inspiration for this post came, let’s talk about the custom collection I used in interface while defining type of Session and ContextItems properties.

    Design goal behind the decision for creating this collection is to provide the same simple feeling working with http context adapter as the one we are used to it while using the real HttpContext.

    Here are some simple examples of  what behavior I wanted to get:

    • var x=httpContextService.Session[“SOME_KEY”]    
    • httpContextService.Session[“SOME_KEY”] =”123”; 
    • httpContextService.Session.Add(“SOME_KEY”,123); 
    • httpContextService.Session.Remove(“SOME_KEY”); 

    And here is what I was trying to avoid:

    • var x= httpContextService.GetSessionValue(“SOME_KEY”)
    • httpContextService.UpdateSessionItemValue(“SOME_KEY”,”123”)
    • httpContextService.RemoveSessionItem(“SOME_KEY”)

    One way to do that is to play again with Adapter pattern and transform HttpSessionState to IDictionary based adapter class and use that adapter type, but that would be solution specific only to this problem and (if there is an option) I always try to solve problem with reusable solutions. The way I have picked for this blog post is simply to create custom name value collection type where I am going to override Add/Remove/Set methods and raise appropriate events informing listeners that certain activity occurred.

    Something like this:

    image

    Here’s the same diagram given through plain old c# code  

    namespace Vuscode.Framework.Abstractions
    {
        using System;
        using System.Collections.Specialized;
    
        public class HookableNameValueCollection : NameValueCollection
        {
            public EventHandler<HookItemChangedEventArgs> ItemAdded;
            public EventHandler<HookItemChangedEventArgs> ItemSet;
            public EventHandler<HookItemRemovedEventArgs> ItemRemoved;
    
            public override void Add(string name, string value)
            {
                base.Add(name, value);
                if (ItemAdded != null)
                    ItemAdded(this, new HookItemChangedEventArgs(name, value));
            }
    
            public override void Set(string name, string value)
            {
                base.Set(name, value);
                if (ItemSet != null)
                    ItemSet(this, new HookItemChangedEventArgs(name, value));
            }
    
            public override void Remove(string name)
            {
                base.Remove(name);
                if (ItemRemoved != null)
                    ItemRemoved(this, new HookItemRemovedEventArgs(name));
            }
        }
    }

    Building HttpContext service adapter

    Once we have IHttpContextService and HookableNameValueCollection implemented, implementing httpcontext adapter is very simple implementation of  the context interface.

    Due to the fact that we would have to reference System.Web in order to adapt certain properties, I will create new component called Framework.Adapters and put the adapter class implementation there.

    Implementation in general would look like this:

    • Redirect method, QueryString collection property and User property would just delegate their calls to HttpContext.Current instance
    • HttpContextServiceAdapter class subscribe to ContextItems and Session add/update/set events and performs appropriate calls to HttpContext.Current.Session and HttpContext.Current.Items

    Let’s take a peek at how this implementation looks like in the C# code …

    #region
    
    using System.Collections.Specialized;
    using System.Security.Principal;
    using System.Web;
    using Vuscode.Framework.Abstractions;
    using Vuscode.Framework.Abstractions.Web;
    
    #endregion
    
    namespace Framework.Adapters.Web
    {
        public class HttpContextServiceAdapter : IHttpContextService
        {
            private readonly HookableNameValueCollection _context
                = new HookableNameValueCollection();
    
            private readonly HookableNameValueCollection _session
                = new HookableNameValueCollection();
    
            public HttpContextServiceAdapter()
            {
                InitSessionVariables();
                InitContextVariables();
            }
    
            #region IHttpContextService Members
    
            public NameValueCollection QueryString
            {
                get { return HttpContext.Current.Request.QueryString; }
            }
    
            public void Redirect(string url)
            {
                HttpContext.Current.Response.Redirect(url);
            }
    
            public IPrincipal User
            {
                get { return HttpContext.Current.User; }
                set { HttpContext.Current.User = value; }
            }
    
            public HookableNameValueCollection Session
            {
                get { return _session; }
            }
    
            public HookableNameValueCollection ContextItems
            {
                get { return _context; }
            }
    
            #endregion
    
            private void InitContextVariables()
            {
                if (HttpContext.Current.Items != null)
                    foreach (string itemsKey in HttpContext.Current.Items.Keys)
                    {
                        _context.Add(itemsKey, 
    				 HttpContext.Current.Items[itemsKey].ToString());
                    }
    
                _context.ItemAdded += ((sender, e) 
    			    => HttpContext.Current.Items.Add(e.Name, e.Value));
                _context.ItemSet += ((sender, e) 
    			    => HttpContext.Current.Items[e.Name] = e.Value);
                _context.ItemRemoved += ((sender, e) 
    			    => HttpContext.Current.Items.Remove(e.Name));
            }
    
            private void InitSessionVariables()
            {
                if (HttpContext.Current.Session != null)
                    foreach (string sessionKey in HttpContext.Current.Session.Keys)
                    {
                        _session.Add(sessionKey, 
    				 HttpContext.Current.Session[sessionKey].ToString());
                    }
    
                _session.ItemAdded += ((sender, e) 
    			    => HttpContext.Current.Session.Add(e.Name, e.Value));
                _session.ItemSet += ((sender, e) 
    			    => HttpContext.Current.Session[e.Name] = e.Value);
                _session.ItemRemoved += ((sender, e) 
    			    => HttpContext.Current.Session.Remove(e.Name));
            }
        }
    }

    Key points:

    • Constructor calls two methods:
      • InitContextVariables – which iterates through all of the  current Httpcontext.Current.Items and populate with their values custom context collection. After that, there’s code which implements event handlers for events published from context custom collection by using the lambda expressions. That’s how when ItemAdded event would be raised it would result with _httpContext.Items.Add method execution
      • InitSessionVariables – same story here. Code first populate custom session collection with the entries already stored in session and then hooks up custom events with appropriate HttpContext Session methods
    • Redirect method just delegates to _httpContext.Response.Redirect() method
    • User property delegates implementation to _httpContext.User
    • QueryString delegates implementation to _httpContext.Request.QueryString

    IoC container context service registration

    Now when we have service contract (IHttpContextService) and service (HttpContextServiceAdapter), the only thing left to be done is registering them into IoC container so presenters can use them in decoupled manner.

    Doing that is very simple… First we add a reference to Framework.Adapters to web application project in order to get access to HttpContextServiceAdapter class. Then we create a simple class called BootStrapper.cs into web application root folder looking something like this

    using Framework.Adapters.Web;
    using Vuscode.Framework;
    using Vuscode.Framework.Abstractions.Web;
    
    namespace Vuscode.Web.WebSite
    {
        public class Bootstrapper
        {
            public static void Init()
            {
                ServiceLocator.Register
    		       <IHttpContextService, HttpContextServiceAdapter>();
            }
        }
    }

    At the end we just add call to Bootstrapper Init method into Application_Start event handler of global.asx so our IoC container would be populated at the beginning of web application life cycle.  

    Solution in action

    Now when infrastructure is in place, implementing HttpContext related logic in presenter  is very trivial

    using Vuscode.Framework;
    using Vuscode.Framework.Abstractions.Web;
    using Vuscode.Framework.ModelViewPresenter;
    
    namespace Presenters
    {
        public class DefaultViewPresenter  : Presenter
        {
            private readonly IHttpContextService _httpContextService;
    
            #region .ctors
            public DefaultViewPresenter()
                : this(ServiceLocator.Retrieve<IHttpContextservice>()){ }
    
            internal DefaultViewPresenter(IHttpContextService httpContextService)
            {
                _httpContextService = httpContextService;
            } 
            #endregion
    
            public void SomeMethod()
            {
                string urlParam = _httpContextService.QueryString[“param”];
                if (!string.IsNullOrEmpty(urlParam))
                    View.Parameter =urlParam;
                if (urlParam == “nikola”)
                    _httpContextService.Redirect(“vuscode.com”);
            }
        }
    }

    At the beginning of the class we have standard poor man dependency injection combined with service locator thing.
    (In case you are not familiar with what I just said go and check one of my Design For Testability (DFT) posts)

    After we would inject the http context service it’s usage is exactly the same as it would be usage based on HttpContext.Current (which was one of the design goal) so everyone in your team should be able to start using it immediately 

    Unit testing HttpContext related presenter code

    The test og SomeMethod given above can be now written before the SomeMethod implementation and it doesn’t require  any Web reference.
    Here is the fragment of the test illustrating how simple now is to test the HttpContext related things in Presenters (complete test fixture code can be found in code sample archive attached at the beginning of this post)

            [TestMethod]
            public void SomeMethod_InCaseOfNikolaParamValue_WouldRedirectToVuscode()
            {
                using (_mockRepository.Record())
                {
                    // setting up the stage
                    SetupResult.For(_mockedHttpContextService.QueryString)
                        .Return(new NameValueCollection() { { “param”, “nikola” } });
    
                    // defining expected behavior
                    _mockedHttpContextService.Expect(x => x.Redirect(“vuscode.com”));
                }
                using (_mockRepository.Playback())
                {
                    var presenter = new DefaultViewPresenter
    				   (_mockedHttpContextService) {View = _mockedView};
                    presenter.SomeMethod();
                }
            }

    As you can see it from code above, to get url needed for test set up all one need to do is to set QueryString property of mocked IHttpContextService to contain desired URL parameters.

    Then I define expected behavior using new Rhino Mock 3.5 syntax for void methods where I said that I expect that redirection to www.vuscode.com would occur.

    Once the recording is over, in playback part I inject the mocked http context service and mocked view and call SomeMethod.

    Ain’ that piece of cake? :)

    What’s next?

    Today I showed how to implement TDD friendly http context and introduced new infrastructure component Framework.Adapters.
    My next blog post would introduce the role of Application controller in MVP (as a ported solution from WCSF)

    ‘till then…

  • Model View Presenter (MVP) – Tips from trenches (TFT) – Base types(Part 1)

    Intro

    RAD tooling style Microsoft is supporting last couple of years usually leads to the code where presentation and bossiness logic are mixed and tightly coupled which makes testability, maintainability and sustainability much more harder then they should be. In case you’ve had to work in the past with web pages containing couple of thousands lines in code behind you will know exactly what problems I am referring to here. In case not, please let me know what is the name of the place where you work :)

    One way to tackle that is using the Model View Presenter UI design pattern which provides clean separation between UI and domain logic and as a result of that come testability of the “UI code”, SRP and SOC principles appliance, clean domain model etc…

    In case you never heard about MVP pattern, before continuing reading this blog posts you might want to take some time and look at Model View Presenter (MVP) pattern (L100). In case you heard about it, but you are not familiar very much with what exactly it is, you might want to read about Supervising controller and Passive view. In case you are wondering what is the difference between MVP and “the one everyone talks about MVC”, I tried to explain that here. In case you are looking for advices on building new web site based on MVP pattern, the guys at Microsoft did great job with Web Client Software Factory, so check that out.In case you knew already all this but never had chance to apply MVP in real world and/or you face some problems applying it in real world, you are at the right place :)

    Purpose of this blog post series is to share with community my experiences on the typical hurdles I was witnessing during the MVP based web site implementation.

    Today’s hurdle: MVP wire up code noiseimage

    (Source code used in today example can be downloaded from here)

    Basically there are couple of ways to wire up  presenter and the view, but after some experiments with constructor based injection and after working for some time with Web Client Software Factory (WCSF) I kind a like setter based dependency injection style.

    Let take a look at that code noise through an example of simple web site with just a single Default page which would have a separate class library project containing view interface (which btw I name following the rule IPageNameView ) and presenter (convention I follow here is PageNameViewPresenter)

    The view interface could look for this example something like this:

    namespace Presenters
    {
        public interface IDefaultView
        {
            int SomeValue { get; set; }
        }
    }

    Here’s the presenter code example similar to a lot of presenters I’ve seen

    namespace Presenters
    {
        public class DefaultViewPresenter
        {
            private IDefaultView _view;
    
            public IDefaultView View
            {
                get { return _view; }
                set { _view = value; }
            }
    
            public void SomeMethod()
            {
                if (View.SomeValue>0)
                {
                    // do something
                }
            }
    
            public void OnViewInitialized()
            {
                // do something on view init 
            }
    
            public void OnViewLoaded()
            {
                // do something on view load 
            }
        }
    }

    Interesting points of presenter code:

    • Presenter has a View property of IDefaultView type
    • how presenter uses  view inside of SomeMethod()
    • existence of two methods which are supposed to be called upon page load and init

    Let’s take a peek now at how the view (default web page) would end wired up with the presenter

    using System;
    using System.Web.UI;
    using Presenters;
    
    namespace WebApplication1
    {
        public partial class _Default : Page, IDefaultView
        {
            protected override void OnInit(EventArgs e)
            {
                base.OnInit(e);
                Presenter = new DefaultViewPresenter();
            }
    
            protected void Page_Load(object sender, EventArgs eventArgs)
            {
                if (!Page.IsPostBack)
                {
                    Presenter.OnViewInitialized();
                }
                Presenter.OnViewLoaded();
            }
            
            private DefaultViewPresenter _presenter;
    
            public DefaultViewPresenter Presenter
            {
                get { return _presenter; }
                set
                {
                    _presenter = value;
                    _presenter.View = this;
                }
            }
    
            protected void Something_Clicked(object sender, EventArgs eventArgs)
            {
                Presenter.SomeMethod();
            }
    
            // Here goes implementation of IDefaultView
    
            
        }
    }

    Key points regarding view code:

    • OnInit method sets the Presenter property value to new DefaultViewPresenter instance
    • Inside of Presenter property setter View property of the presenter gets web page pointer casted to IDefaultView.
      Effectively, presenter gets injected with a view implicitly cast to view interface
    • Inside of page load method, presenter OnViewInitialized method is get called if the page is not postbacking itself
    • Inside of page load method, presenter OnViewLoaded method is get called regardless of postback
    • Last interesting moment here is how Presenter is get called  from a view in Something_Clicked event handler

    Hurdle summary

    Writing all of this code for every web page and every control (I will speak about this in later posts) is very tedious and repetitive task. Using WCSF helps a bit because code similar to this gets generated but still that’s a lot of lines written just in order to enable us to start to work on a page.

    Luckily, there is solution :)

    The solution of today’s hurdle would be encapsulating all of the code noise in set of base classes.

    The design goals here are:

    • define generic presenter which would be using generic view interfaces
    • define generic view which would perform automatic wire up to generic presenter

    Let’s see one way how this can be done….

    (My solution is based on Mario Szklanny’s Web Client Software factory solution, which I adopted for use outside of WCSF)

    Generic presenter

    The code related to this goal will be stored in a class library which I call Framework.

    Purpose of Framework assembly is to contain all the basic functionality required for most of the code regardless of it is web/UI related or not. image

    That’s why beside the MVP related code there would be (in my case):

    • ServiceLocator type (with code similar to what was described in  DFT Unity  blog post)
    • BaseClass and BaseCollection (very light, providing only basic functionality I personally use in debugging. Definitely NOT supposed to be  god class
    • More other things I won’t mention here (I would be adding them in the upcoming posts so I don’t want to spoil the surprise :))

    (In case you are puzzled with reasons behind having Rhino.Mocks reference in Framework, check this out)

    Key concern related to this class: No heavy dependencies and definitely no System.Web related references. This component is supposed to be able to be referenced by any component in application

    The IPresenter interface defines very simple generic presenter attributes

    namespace Vuscode.Framework.ModelViewPresenter
    {
        public interface IPresenter
        {
            object View { get; set; }
     
            void OnViewInitialized();
     
            void OnViewLoaded();
        }
    }

    OnViewInitialized and OnViewLoaded are methods we saw in above code as the ones handling calls from Page_Load method. The reason behind the fact that View  is of object type is that we can box any class to object type so we can store reference to boxed form of any view

    Generic Presenter class implementing the IPresenter interface could look like this

    namespace Vuscode.Framework.ModelViewPresenter
    {
        public abstract class Presenter<TView> : IPresenter
        {
            public TView View { get; set; }
    
            #region IPresenter Members
            
            object IPresenter.View
            {
                get { return View; }
                set { View = (TView) value; }
            }
    
            public virtual void OnViewInitialized()
            {
                /* do nothing*/
            }
    
            public virtual void OnViewLoaded()
            {
                /* do nothing*/
            }
    
            #endregion
        }
    }

    Looking at the code above one could realize next things:

    • Presenter class is abstract generic class accepting  TView generic parameter and implementing IPresenter interface
    • The two methods are implemented as virtual because we don’t want to enforce implementing this methods in each one of presenters inheriting generic presenter because some of them might not need some of those methods
    • The object View property defined by IPresenter interface is implemented explicitly which effectively hides it from the classes inheriting generic presenter
    • The fact that TView View property is public, combined with mentioned explicit implementation of the object View property effectively constrained View to TView

    Generic viewimage

    One of the main design principles I am trying to stay with is that Presenter assembly is not allowed to be dependable on System.Web directly or indirectly and therefore due to the fact that Presenters will reference the Framework, I can not put there generic view. 

    The reason why I can not do that is based upon the fact that each one of the pages would inherit from that base generic view, so generic view needs to inherit from System.Web.UI.Page

    All of the “base web UI” functionality I would keep in component called “Web.Base”

    From the solution explorer snapshot on the right side, we can see that project consists of 3 base views: page, control and master page. (Yes, I am applying MVP pattern even on the master page)

    using System;
    using Vuscode.Framework.ModelViewPresenter;
    
    namespace Vuscode.Web.Base
    {
        public abstract class ViewBasePage<TPresenter> : LegacyBasePage 
    						where TPresenter : IPresenter, new()
        {
            private TPresenter _presenter;
    
            protected ViewBasePage()
            {
                Presenter = new TPresenter();
            }
    
            public TPresenter Presenter
            {
                get { return _presenter; }
                set
                {
                    _presenter = value;
                    _presenter.View = this;
                }
            }
    
            protected virtual void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    Presenter.OnViewInitialized();
                }
                Presenter.OnViewLoaded();
            }
    
        }
    }

    Interesting moments here are:image

    • ViewBasePage is  abstract generic page where the generic parameter is constrained to type implementing IPresenter interface
    • ViewBasePage inherits from LegacyBasePage
      Most of us have some base page already in our web sites. This illustrates that the ViewBasePage should inherit from that page and then all of the MVP pages would therefore get access to that legacy base page and inherit all of the MVP related code
    • Rest of the code is the same code we had on default page just pulled out to base page level

    Code for generic view of control and master page is exactly the same as the page one with only difference from which base type they would inherit (UserControl or MasterPage)

    Solution in action

    Having Framework and Web.Base component built, would enable us to make changes in presenter and view which would cause them to look like this at the end

    View (Default web page)

    using System;
    using System.Web.UI;
    using Presenters;
    using Vuscode.Web.Base;
    
    namespace WebApplication1
    {
        public partial class _Default : ViewBasePage<DefaultViewPresenter>
    				    , IDefaultView
        {
            protected void Something_Clicked(object sender, EventArgs eventArgs)
            {
                Presenter.SomeMethod();
            }
    
            // Here goes implementation of IDefaultView
           
        }
    }

    The page just inherited form ViewBasePage<DefaultViewPresenter> and all of the plumbing code is gone from the page

    Looking much better, isn’t it? :)

    Presenter

    Presenter is even simpler

    using Vuscode.Framework.ModelViewPresenter;
    
    namespace Presenters
    {
        public class DefaultViewPresenter  : Presenter<IDefaultView>;
        {
            public void SomeMethod()
            {
                if (View.SomeValue>0)
                {
                    // do something
                }
            }
        }
    }

    All presenter had to do is to inherit from Presenter<IDefaultView> in order to get View injected and potential to override OnViewXXX methods

    Looking much better, isn’t it? :)

    What’s next?

    Today I showed how to remove code noise from the MVP related types and also set up the foundations of two components: Web.Base and Framework. My next blog post would be expanding a bit framework component in order to show how to work with HttpContext related concepts and values without referencing System.Web into presenters

    ‘till then…

     
  • Model View Presenter (MVP) – Tips from trenches (TFT) - Announcement

    I have blogged already in the past about MVP basics, MVP vs MVC, MVP Passive View and MVP Supervising Controller but recently I had some interesting experiences in applying MVP into real world applications and from that endeavor I learned couple of things and get answers on couple of common questions which I would like to share with community.

    To me, the most interesting part of this experience was that some of my MVP based coding was done using Web Client Software Factory but part of MVP coding was done without it, so I had to “port” WCSF features to standard asp net application. I would describe pieces of that port which (I guess) would be interesting for the ones not being able to sell WCSF to their managers but still wanting to use MVP in their ASP NET development.

    Another thing I would try to explain is something a lot of people don’t know: Microsoft MVC .NET framework consist of two separate parts: MVC and routing engine. In other words, routing engine is not part of MVC design pattern and it can be used with WebForms too…

    Another very important thing in real world MVP development I would try to demo is how to introduce MVP pattern usage in legacy components where the legacy model is not written in decoupled manner (Separate interface, Adapter and Translator design patterns)

    Last, but not the least, I would show how MVP pattern is looking combined with ServiceLocator I presented in Design For Testability blog post series and show examples on how to test MVP

    Once I finish presenting all this, I would use presented concepts in showing how “one interesting "real world" example” would look like done with MVP pattern and standard WebForms

    So, MVP fans stay tuned for the posts to come very fast. People not interested in MVP, please be patient… I just need to nail down MVP , “once for all” :)

    Disclaimer: The purpose of this blog post series will not be showing that MVC based web development is worst then the MVP one. MVC is awesome but unfortunately requires too big investments to be introduced in existing large web forms web applications (most noticeably the need for redesigning all code which relies on page event life cycle). For those brownfield scenarios, I found MVP much easier to be implemented and adopted by webform developers then the MVC.

  • Adobe Air 2008 Tour – Prague

    For a few of you reading my blog, this blog post would most definitely come as a big surprise knowing how passionate iPhone 172
    I am about SIlverlight and all related stuff.

    Well, although I believe that the real thing is Silverlight, I wanted to check out how the “other side” looks like.

    Considering the facts that level of my previous experience with DW, Flex, Flash and Air was zero and the fact the sessions have been presented in Staropramen brewery building I anticipated a lot of cool thing to learn and some beer to be drink.

    Both of my expectations were fulfilled.

    Before I start

    Before I start “pasting” my notes and observations from the OnAir  Adobe day, I can not avoid mentioning first the other event organized last week by Microsoft here in Prague, “Silverlight for developers”

    Not to be too much inflammatory here, I would just say that I was really disappointed with this Microsoft event.
    I was there only one hour because I didn’t want to waste of more time but during that time:

    • I saw a demo how small “flash like” games you can make with Silverlight
    • I saw a demo how with Silverlight 2.0 can make media player
    • I saw a bunch of false information's about competitors (e.g. Flash/Flex not supporting web service calls)
    • I saw whole one slide about Silverlight architecture shown in about 15 seconds and 4 sentences
    • I saw the same egg example used at literally every Silverlight presentation here

    What I didn’t saw there in that one hour is:

    • Presenter excitement about breaking and revolutionary new technology SL truly is
    • Business value Silverlight has (beside games and video players)
    • That Silverlight is NOT media player plug in
    • A big picture about how Silverlight relates to ADO Net Data Services, FeedSync, Entity framework etc
    • Why I should choose Silverlight instead of Ajax, WPF, Flex, Flesh, Air etc

    Anyhow, I saw a bunch of people taking notes so I guess the decision to make sub L100 session was the right one after all for majority of developers attending the presentation.

    Keynote

    Keynote was done by Ryan Stewart (rstewart@adobe.com,twitter:ryanstewart) who is Adobe Program Manager.

    His main points were that Flash is deployed to 99% of the computers with 8 million installations/day, with a very efficient flash sandbox update mechanism (when they roll out Flash 9 it took them only 12 months to complete update of most of Flash 8 sandboxes runing on client computers)

    He pointed that they have a long wining tradition of being the trend setters (Acrobat reader 1993, Adobe Flash 1995, Adobe Air 2008)

    Then he outlined their vision with a nice diagram showing the Adobe ecosystem where Flash covers the web needs, AIR desktop segment with Flex  providing client framework for both of them

    <place for diagram>

    Flash 9 has significant improvements in areas of multilingual support and localizations enhanced visual performances (with GPU hardware rendering, Rich media support and Dynamic streaming (streams optimized per user bandwidth), 3d visual effects (transitions and transformations)

    Most of the thing they mentioned as new in Flash 9 I can see similar to Silverlight/IIS7 stack and that is great because Flash/Silverlight crosspolination would bring only benefits to us developers

    And then he mentioned what is Adobe Air… :)

    image

    “Adobe AIR enables web developers to use existing technologies to build and deploy rich Internet applications on desktop

    My first reaction was:”Dough?”. I came here to see how Air compares to Silverlight and realized that they are not competing at all. In fact they are two technologies taking totally opposite directions:

    • Silverlight takes direction where he moves desktop programing model (WPF, .NET) to web by executing “desktop” code in SL sandbox
    • Adobe Air is opposite allowing web programing model (jscript, html, css) to be executed on AIR Sandbox allowing us doing the desktop applications using Web technologies

    I would say that behind that technology differences, there are two different business models Adobe and  Microsoft are playing on:

    Adobe plays on the fact that web applications and web developers are already deep into the enterprise so reusing the already built web applications “free of charge” in desktop environment and the same skill set of web developers. Sales pitch: “you already have the site. desktop enable it!”

    Microsoft sales pitch (IMHO) is slightly different:“We know how hard is to do web development so we have a sandbox which removes the need for web development. You just do the “client like" development without having to face the same problems you are facing now.”

    Ryan then show couple of demos, how RIA desktop application can look

    image

    image

    image

    He showed web application application done for NY Times http://www.shifd.com/ which has support for Air and demo how web site and client application cooperate. He also showed how you can SMS the data and told that iPhone support exist. Having the same app running on multiple platforms (Air and Silverlight) looks very important to both Adobe and Microsoft which I can understand considering how Mobile market is getting more and more business value .

    shifdexample

     

    He summarized at the end why we would like to do to RIA AIR development at the end:

    - Persistent connection (offline support)
    - Branded experiences (not limited by browser, pick your won window shapes etc)
    - Desktop functionality (file system, notification windows, SQLLite local DB support)
    - Data access (REST, HTTP, SOAP - same as you do in Web)
    - Efficient development 

    Building AIR application can be done free (There is free AIR free SDK and Flex SDK) but for best productivity use:

    -  Adobe products –> Fx, Dw, Fl (support for debugging, packaging for Air) or
    -  Eclipse Aptana  which is 3pty tool plug in for Eclipse

    Air future: Air 1.5 version would sync with Flash Player 10, sync up with WebKit capabilities.

    For more general level information's he recommend use of a central URL: http://www.adobe.com/go/ria 

    Hello world  in Adobe AIR

    Mike Chambers (www.mikechambers.com)  then had a small session showing how to do do hello world application using Flex Builder and AIR

    He pointed that Flex Builder is built on top of Eclipse.

    It was standard presentation where he created new Flex Project, picked on second screen that he wants to create desktop application and the default project was created (check out Flex 3 help file for how to build AIR applications with Flex 3 for detail instructions)

    Default project has two application files:

    AIRHelloWorld.mxml root application file which would be compiled to swf containing markup and ActionScript/JScript code
    AIRHelloWorld.xml - application description file (defines metadata needed by runtime: filename, files needed etc)
    Some of the elements defined in application setting xml file are:

    • <id> - unique app identifier com.mikcehambers.AIRHelloWorld (not seen by users)
    • <name> - name of application (user sees, add/remove programs, shortcuts etc)\
    • <version> - exposed to application used for auto update
    • <description> simple description which would appear on installation screen
    • <initalwindow> - elements specifying how app launch and how it looks when launch
    • <systemchrome> – values: STANDARD/NONE) – standard gives the standard windows chrome regardless of what OS user have,  none gives opaque window, without maximize, minimize buttons, title bar etc
    • <transparent> (used in combination with systemchrone -> none with true window allows having irregular shape windows)
    • <visible> default false! Once the app is ready to go set it to true (Dynamic layout)

    Note: Adobe MXML looks very, very similar to XAML!. Not sure if they have cool stuff like extensions, dependency and attached properties etc, but I can read MXML markup code without any problem

    Once the hello world app got a button in center of window and a AIR logo image in right corner, Mike exported it to release build (Project/Eporrt to release build menu item). Interesting thing regarding the building process is that AIR applications HAVE TO digitally signed (one of wizard steps ask for certificate location – with an option of temp signing in)

    This is how installing AIR application looks like
    image image

    And the message I got on my lap top after that :) (installed app was still working after that )

    image

    After hello world app was done he spoke about jscript to Air book and Flex reference poster, pointed to  www.tostring.org web site which contains online version of those books and to http://onair.adobe.con/blogs/tour as place where to go to grab presentation material from presentations made on tour.

    Adobe AIR done with Jscript

    This presentation was done by Kevin Hoyt (khoyt@adobe.com, http://blog.kevinhoyt.org) which started his presentation by doing a demo of CleVR.com site done in AIR where he uploaded couple of his panorama photos he made yesterday with his 10 MPix camera. The site took couple of his pictures and stitched them into one panorama wide picture. He emphasized couple of times that the pictures are very big and that the AIR app is smart enough to melt them together resolving their intersections automatically.

    Who said Silverlight DeepZoom? :)

    He used FlexSDK (can be downloaded from here  for free) together with Notepad (whatever the OSX name for Notepad app is) and showed how a simple standard HTML page with standard HTML tags would execute on on desktop.
    Beside the free tools, DEV could download the Dreamweaver CS4 beta from labs.adobe.com or download a AIR extension for Dreamweaver CS3. Another option is 3pty plug-in for Eclipse called Aptana which contains (beside other things) a lot of examples how to do most of  the common activities with AIR.

    He presented then very important file in FlexSDK, AIRAliases.js which performs mapping of AIR types to jscript classes.

    That’s how while working with jscript classes you are using in fact the AIR. He showed a demo of how from jscript code he can  write files to local hard drive using the mapped functionality

    He pointed also to two different commands for adl and adt (where adl allows testing air application without installation – useful for real world development)

    Integrating HTML, JavaScript and ActionScript ("ScriptBridging")


    Kevin Hoyt also did the next presentation called script bridging where he show different examples of integrating different scripts.

    He was using on this presentation Flash CS3 to show couple of demos:

    • Drag & drop functionality
    • Accessing CSS elements directly from AIR
    • How to create a browser wit some cool extensions
    • How FlexBuilder enables browser DOM debugging directly in ActionScript.

    An example of how to access DOM he used was through htmlLoade class, something like this

    web.htmlLoader.window.document.getElementById('txtName').value;

    An example of how to access flash library from AIR

    air.FileStream = window.Runtime.flash.filesystem.FileStream

    He showed also a demo of jscript application reading the content of the zip file using the library.swf ActionScript library done by David Cheng directly by jscript. According to him, this approach allows us (even if we want still to  keep jscript applications to enrich them with functions they wouldn’t have without script bridging.

    At the end he mentioned that on his blog (http://blog.kevinhoyt.org) example with zip library, custom hrome and custom grid done with CSS and jscript can be found

    Czech Flex user groups

    After the lunch (Staropramen beer, lots of tasty food on a perfect day – thanks Adobe! :) ) we had two short presentations on Czech/Slovak.

    First one was presentation of Flex user group done by Juraj Michalek (www.flexgarden.net).
    Key points: bunch of Air and Flex online seminars on their site and he said they are very willing to provide their help through their Flex user group at
    flexgarden@googlegroups.com

    Second presentation was done by authorized Adobe partner which host the   www.flash.cz site with more then 60 articles for beginners  on flash and flex and also with expert answers provided for Flex developers.

    Deploying and updating AIR applications

    Platform Evangelistsimage
    Serge Jespers
    serger@adobe.com
    http://sergejaspers.com

    Jasper showed how to deploy and update AIR application in 3 simple and straightforward steps

    1. Get your application signed
      Adobe AIR application have to be signed by some certificate so during the installation of AIR application publisher identity would be known (green icon). He mentioned that most of certificates we have now would probably be ok for AIR. In case we don’t have any certificate he recommended buying one for $299/year from thawte.com)For a limited number of applications uploaded to Adobe AIR Marketplace , Adobe would provide complimentary code signing certificate (http://adobe.com/go/marketplace )
      Once we have the certificate, signing application is very easy: all we need to do in Step 2 of publishing AIR application we need to provide location of certificate file and password and that’s all.
    2. Deploy your application
      Bad way to do that – zip air app and provide a link on site – sucks big time
      Good way: use installation badge which is kind of customized installation screen where user clicks on install button
      and the application install application and AIR (after showing two security informational screens) .
      Adobe provides 3 types of badges: standard, beta and custom.
      1. Standard is available in AIR SDK, ready to use now but only with standard use cases. Source available
      2. Beta badge – available on http://labs.adobe.com. Cool new look and extra features (can show video, help functionality)
      3. Custom badge – developer have to define everything. Most powerful, but also most complex to implement
    3. Update your application in five simple steps (Adobe “ClickOnce”)
      1. Check from application if server contains XML update file  containing information on current application version
      2. Check then if installed application is older then version on server
      3. Create instance of the Updater class
      4. call Updater.Update method
      5. Updater would close AIR app, install new version and then restart the Application

    Application update – DONE!

    ==============================================

    AIR API Overview

    Daniel Dura
    www.danieldura.com, ddura@adobe.com 
    Platform evangelist, Adobe

    iPhone 113iPhone 114DB support darag&drop clipboardmisc

    All of the examples he presented are available on his web site illustrating all of the common usage scenarios.

    He was speaking about 6 major API function groups

    1. Window API major API features:
      - Multi window support
      - Transparent windows
      - Window types  (Standard, Utility and Lightweight)
      - Z-Ordering
      - Always in front window
    2. File I/O major API features:
      - Full Read/Write access
      - Native File dialogues (save, select, select mutliple, directory)
      - Async and Sync APIs
      Note: I really don’t get why Adobe supports async mode. Due to the fact that browser is single threaded, file I/O operation would block the whole browser. To me that feature looks like a nice rope Adobe gave us DEV to hang ourselves :)
    3. Database support
      SQL Lite DB support
      Zero setup single file
      SQL Lite stores all data in one file using applicationStorageDirectory comand –> (Silverlight IsolatedStorage)
      SQL Lite supports transactions and the sql code executes 10x faster when using transactions (reducing number of file I/O operations)
      To me SQL Lite is trying to do exactly the same as Microsoft Compact SQL Server with more limited stack of operations.
    4. Drag & Drop/Clipboard
    5. Web services support
      He showed an example how to detect internet connectivity status by pininging google.com  by doing something like this
      new UrlRequest(www.google.com) class
      request.method="HEAD";
      URLMonitor(reuest)
      monitor.addEventListner(StatusEvent.STATUS, handle_status)
      monitor.start();
    6. Misc - Encrypted local store
      - dock notifications
      - idle notifications

      

    Google App Engine

    Dion Almer, cofounder ajaxian.com, works at Google code

    iPhone 121iPhone 123

    At the beginning he showed http://prague.360cities.net/ flash application powered by google maps  which looks to me as Microsoft Deep Synth competitor (Altpught DeepSynth is much more serious, compare their example with the one from 360cites site)

    The rest of the session he was speaking about Google app engine which should help building developers scalable sites in Python for free (to up to 5 million page views)

    Another Interesting thing (I’m sure my friend Lorenzo Bolognini already knows about it)  is that Django Python framework is fully supported (except ORM features)

    http://code.google.com/appengine

    Another interesting question he answered was”

    “What if popular JavaScript libraries were available and shared in the browser?“

    Well, instead of each one of us hosting jscript libraries, Google host at http://code.google.com/apis/ajaxlibs/ jscript libraries for jquery, 

    Data intensive AIR Applications

    Andrew Shorten

    iPhone 126iPhone 128  iPhone 130

    I was expecting a lot from this sessions because seeing what Adobe has to offer in this area is very important for LOB applications/sites, but I get the least from this session.

    The reason why lays in the fact that most of his presentation was wrapped around Adobe specific Blaze DS and Live Cycle server which are providing server side infrastructure for efficient RPC type of communication.

    He showed example from http://www.jamesward.com/census on what performance gain usage of Adobe servers  brings to game which looked nice but he mentioned that the data transmitted is in binary format (AMF3) with RPC which is not very firewall friendly. In post RPC era I believe we are messaging should be done by open protocols on firewall friendly ways

    The difference between the Blaze DS server and Live Cycle server (beside Blaze being Open Source solution) is that Live Cycle server supports offline scenarios allowing applications talking to services to work even application would be offline and Live Cycle Data Service server would take care about  synchronization and conflict resolution once the Internet connection would be up again.

    Live Cycle Data Management services have XML configuration file (like the BlazeDS has) where user defines SQL adapters with the sql scripts. Original CRUD operations are modified there to support the offline/online updates which occurs on commit (and use the xml defined data). So we have a XML file filled with dynamic SQL statements. Good thing that none of the DBE were not attending because I’m sure there would be DBE yelling  in that moment.

    To me this example looked very familiar with “Astoria offline” demo from Mix ‘08 and I am feeling much more comfortable with solution based on REST Atom services/ FeedSync based solutions (which is btw free) versus something which looks like closed Adobe product.

    Couple of useful links:

    Blaze DS
    http://opensource.adobe.com

    Live cycle (additional options as support for offline, conflict resolution etc)
    http://www.aobe.com/products/livecycle (1 CPU license for free)

    http://www.adobe.com/devnet/livecycle

    AIR + Ajax


    Andre Charland, CEO, Nitobi.com
    Enterprise Ajax book, RobitReplay.com, InsideRIA blog
    http://blogs.nitobi.com
    http://www.insideria.com
    twitter.com/andrecharland

     iPhone 135iPhone 138   
       iPhone 146 iPhone 140 iPhone 148

    This guy REALLY likes jscript. According to him we should be all doing jscript everywhere and anytime. And the examples he showed give him a lot of credibility in that :)

    Why Ajax in AIR?

    - Code reuse (we already have a bunch of jscript code)
    - Skill reuse (we already have a bunch of jscript developers)
    - HTML is REALLY good at some things ( build blog reader only in flash is not having sense)
    - maintain UI patterns (same UX for web and desktop)
    - JavaScript interest in DEV community is growing  (important if you are hiring)

    He showed some data graphs about sales of programming languages books showing that jscript interests is growing rapidly.

    He demo couple of very interesting applications using AIR:

    • AIR twitter client: www.getsnitter.com (jQuery, custom chrome, transparent, word count, notifications)image
    • SalesForce.com desktop client done in AIR (adobe tree controls, drag and drop of vCards)
      image
    • Robotreplay – story of usability with youtube example where everything user is not looking directly is blurred
    • MacDoc wanna be – fisheye , jscript, css and png files rotating
    • Spreadsheet like greed  (Wizard defining data binding of grid, column mapping, live scrolling or paging etc
      Dreamweaver creates php, jscript, css)
    • Nice bubble tooltip creation tool
    • ReadAIR – jQuerty built google reader clone
    • Snippetly – stores code snippets in SQL LIter (writen in jscript using Mootool linrary)
    • VOIP and SMS in AIR demo
      Tabria  client which calls the phones of both of people in chat using the local lines and allows them to talk over the Tabria network and/or to send SMS messages

    Then he was speaking about some usability pitfalls in AIR:

    - Keyboard shortcuts
    - Minimize, move close when "chromeless"
    - Mouse hints, invitations, tool tips

    Activity indicators have to be implemented explicitly

    At the end he mentioned that http://www.nitobi.com/air has bunch of useful links

    nitobi.com/air
    has bunch of links

    AIRconditioning

    Lee Brimelow
    Platform evangelist/Adobe

    http://www.gotoandlearn.com (free video tutorials about flash)
    http://www.theflashblog.com  (all of the slides he was presenting should be there)
    (worked at frogdesign  before adobe)

    iPhone 152      iPhone 163
    Lee did awesome job showing us what we can do with AIR in very funny way. His presentation started with “Flash vs Flex” where he recommended:

    • use Flex when in need for : Application layout, data binding, superior coding expereince, components sets
    • use flash when in need for: Animation, Video etc…

    He then started doing his demos:iPhone 156

    1. Windowing demo He presented an application creating different types of windows (Normal, Utility
      and Lightweight) combined with different Chrome options (System, Custom (Opaque) and
      Custom (Transparent). He also showed “staying on top” of windows and full screen mode  where air capture keystrokes even in full screen mode.
      Examples he used to show this were:
      - Hell’s kitchen custom chrome video player, 
      - a nice sidebar staying always on top with a collection of buttons producing different farts
      (Seeing that no one is laughing on that, he said “This would be really funny in US”)

      - Boss application
      He opened a game and a Safari with PiratesBay site where he typed CS3 and the list of pirated version with pirated serial keys downloads appeared (really funny), and then he press the boss key and  
      iPhone 159iPhone 160iPhone 161
      - Papervision 3D
      Thanks to using of GPU hardware acceleration, he showed really fast 3d carousel with live videos
    2. Menu-ing API
      He presented that AIR supports OSX Application menu and Windows\Linux window menu (menu attached to application window, under title bar)
      Developer have to do checks in the code during the run time to see if a given type of environment supports some type menu or not. He showed support for Dock menus (Mac only) and System tray menu(windows).
      An example he used to demo the functionality is called :SpitEmOut and it is awesome minimalistic video player with snapshot capabilities , where every snapshot taken is randomly aligned around video player
       iPhone 167iPhone 170iPhone 169
      When he was showing that context menu is not containing any “About Adobe Flash” entries (fully customizable) he called that “no Adobe usual crap in menus”   Hilarious …
    3. File class
      Worth of mentioning here (which was not mentioned before) is that AIR is in advantage over the Flash 9 with file related functions, but Flash 10 would have all the AIR file features (writing to local disk, reading from disk etc). The size of encrypted local storage is 10 Mb per application and encryption used is the default one of the user OS
      Example he tried to show to us was downloading FLV file from you tube but that didn’t work (my guess due to WiFi network being down at that time)
    4. Drag & drop functionality
      Supported D&D modes:
      - Application <->Desktop
      - Application <-> Application
      - Application <-> Browser
      You can customize the drag & drop picture.
      Example: Flash video player dragging the FLV video file to video player example
    5. OS Interaction.
      Supported: - Launch on user login mode
      - File associations (full manipulation)
      - Tracking user presence (application is aware of user being idle where idle threshold must be more then 5 seconds) - Control over application invocation and termination through appropriate events
      - Only one instance of one AIR app can run at the same time
      Example:
      Vista UAC
      ------------------iPhone 168

      The example he had was targeted to Microsoft and Vista UAC. He made a  little app which was after user was idle for 5 seconds popping up a dialog with a message like "Are you sure that you want to move mouse?"  in a dialog box looking like Vista dialog box (grayed background, system colors etc)
      A bit to much Mac-ish for my taste. Speaking about Macs: guys from Adobe looked really surprised when they saw a minority of people raising hands on “Who’s Mac owner”… I guess that’s because in US Mac has much higher penetration in the Adobe user group. Each one of the presenters was using Mac for its presentation


      FileTyper virus
      -----------------------------
      With AIR you can associate any file type on user computer to AIR application. He showed an example where he switched application handling the FLV files to start up his GoogleAds AIR application.
      I can see a bunch of people trying to do the same thing and I am not sure how AV software would prevent this because in a sense it is not real virus but the effect (in case of most users) would be the same as you have Trojans in your computer
      WiFI example
      -----------------------------
      AIR can get information from Wireless card about available networks. He used this example to show us how to pass start up parameters to AIR application. Also he showed network connectivity  AIR functionality together with cross application communication (AIR to AIR, AIR to SWF (through local connection)

    Conclusion

    Adobe organized great event here in Prague where even persons like me (new to Adobe ecosystem) get a lot of important information's.

    To me the most important thing I was hoping to get answer on was: How Adobe offerings compare to Microsoft Silverlight stack.

    The answer I got can be summarized as: Adobe doesn’t have a chance on long run. The only thing they have huge advantage is  Flash plug in penetration (99% of browsers) but IMHO is just matter of time when MS would get similar figures with SL.

    Here’s the comparison (although it is hard to figure out what to compare “AIR vs SL” or “AIR vs WPF’

    Languages

    Adobe is limited to ActionScript and jscript. Silverlight supports CLR (C#, VB)  and  DLR langauages (Iron Python and Iron Ruby) - including even php support through Phalanger project.

    The decision Microsoft made in SL 2.0 to get rid of the jscript in favor of .NET languages is perfectly fine with me.

    Tooling

    Although I was surprised with how good Flex Builder 3 and Flash IDE’s are (thanks to Eclipse) my opinion is that they are still not match to VS IDE offerings (standard with or without plug ins).

    Microsoft Blend in version  2.5 is “still not right there” but it is making big steps toward being designer friendly tool. IMHO, all Blend needs is mainstream adoption from designers which would bring significant feedback “from the trenches” which is only thing Blend team need. I am not even sure that the people criticizing it is not criticizing it because mostly “it is different then Flash”… Ah, time would tell about this

    Very important difference here between the platform is that (according to demos I saw) there is no “code behind” in Adobe case (markup and ActionScript code are mixed) which definitely makes  life difficult in case of multiple personas working on the same file (conflict resolutions etc)

    DB support

    Microsoft SQL Compact and Adobe SQL Lite look like doing the same thing on same way (no installation, app local database). I am biased a bit, but SQL Compact coding model (standard ADO NET code) looks more robust and powerful then the one I saw for SQL Lite

    Web services

    We are living in SaaS and S+S era, so Adobe proposal of using propitiatory AF3 binary format with RPC communication style looks not very convincing.
    In Microsoft stack we have WCF supporting a bunch of different messaging protocols. There are a