SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Downloaden Sie, um offline zu lesen
Parsley                        &
                       framework for Flex/Flash/AIR




Alexander Budjakov
Flex Developer
prideconan@gmail.com
Parsley is all about decoupling
Overview
Parsley is Open Source, licensed under the Apache License 2.0
Written by Jens Halm
First version 1.0.RC1 (2007-12-09)
Last version 3.0.0 (2012-02-06)    > 4 years

Parsley is an Application Framework for Flex and Flash Applications built upon an IOC
Container and Messaging Framework that can be used to create highly decoupled
architectures.
Features


           Parsley                           Spicelib
Flexible IOC Container              Command Framework
Dependency Injection                XML-Mapper
Decoupled Bindings                  Reflection API
Messaging Framework                 Logging
Managed Commands
Dynamic View Wiring
Advanced Modularity
Object Lifecycle
Localization
Extensibility
Inversion of Control (IoC)
Inversion of Control (IoC)
 Hollywood Principle: Don't call us, we'll call you.




                           Program logic runs against abstractions
                           such as callbacks
IoC Example
Here is the simplest possible                          Here are a common smells that should lead
IoC component                                          you to refactor to IoC
package com {                                          package com {
   public interface IMap {                                public class GPSNavigator implements INavigator {
      //methods                                              private var map:IMap;
   }                                                         public function GPSNavigator() {
}                                                               this.map = new UkraineMapImpl();
                                                             }
package com {                                                //other methods
   public class GPSNavigator implements INavigator {      }
      private var map:IMap;                            }
      public function GPSNavigator(map:IMap) {

      }
         this.map = map;                                              Some other smells.
      //other methods                                  package com {
   }                                                      public class GPSNavigator implements INavigator {
}                                                            private static var map:IMap = MapFactory.getMap();
                                                             public function GPSNavigator() {
                                                             }
                                                             //other methods
                                                          }
                                                       }


                                                                    It is hard coded
                                                                    Not reusable.
IOC Container
 We may ask for the object from the container and the
 container creates the object and its dependencies


                                              <interface>
    EBookReader
                                                  File


     inject

                     creates
                                  PDFFileImpl               TXTFileImpl

   IoC Container



Parsley is a classic IOC Container. It provides support for Dependency Injection,
Object Lifecycle Management and Messaging
Dependency Injection (DI)
Dependency Injection (DI)
[Inject]       The core feature of any IOC Container




                             How objects obtain references to each other
Dependency Injection (DI)

       You may have these different tools
Dependency Injection (DI)

        You may have these different tools




       OR just one tool with attachments
Dependency Injection (DI)

        You may have these different tools




       OR just one tool with attachments

             This brings us to the Design Principles -
             Program to an interface, not an implementation
Dependency Injection (DI)




    Three ways of classic DI
Dependency Injection (DI)
                        public class Controller {
                           private var model:Model;
                           public function Controller(model:Model) {
Constructor Injection         this.model = model;
                           }
                        }
Dependency Injection (DI)
                        public class Controller {
                           private var model:Model;
                           public function Controller(model:Model) {
Constructor Injection         this.model = model;
                           }
                        }




                        public class Controller {
                           private var _model:Model;
                           public function set model(value:Model):void {
  Setter Injection            _model = value;
                           }
                        }
Dependency Injection (DI)
                        public class Controller {
                           private var model:Model;
                           public function Controller(model:Model) {
Constructor Injection         this.model = model;
                           }
                        }




                        public class Controller {
                           private var _model:Model;
                           public function set model(value:Model):void {
  Setter Injection            _model = value;
                           }
                        }



                        public interface IController {
                           function injectModel(model:Model):void
                        }
 Interface Injection    public class Controller implements IController {
                           private var model:Model;
                           public function injectModel(model:Model):void {
                              this.model = model;
                           }
                        }
NOT Dependency Injection

           public class Controller {
              private var model:Model;
              public function Controller() {
                 model = new Model();
              }
           }


           public class Controller {
              private var model:Model;
              public function Controller() {
                 model = ModelFactory.create(Model);
              }
           }


           public class Controller {
              private var model:Model;
              public function Controller() {
                 model = Model.getInstance();
              }
           }
IoC and DI Benefits
•   Dependency management
•   Simplify the reuse of classes or components
•   Offers configuration flexibility
•   Simplify unit-testing
•   The "cleaner" code
Configuration and Initialization
Configuration and Initialization

       • Telling the IOC Container which classes it
         should manage
   1   • MXML, XML, AS
<?xml version="1.0" encoding="utf-8"?>
UserConfig.mxml   <parsley:Objects xmlns:fx="http://ns.adobe.com/mxml/2009"
                     xmlns:s="library://ns.adobe.com/flex/spark"
                     xmlns:mx="library://ns.adobe.com/flex/mx"
                     xmlns:parsley="http://www.spicefactory.org/parsley">

                  // *hidden imports

                  <fx:Declarations>
                     <parsley:Object id="userModel" type="{Model}" lazy="true"/>

                    <parsley:DynamicObject type="{Counter}">
                       <parsley:Property name="maxCount" value="100" />
                    </parsley:DynamicObject>

                    <parsley:View type="{UsersView}"/>

                    <service:MockUsersService />

                     <parsley:MapCommand type="{GetUsersCommand}"
                                         messageType="{GetUsersMessage}"/>
                  </fx:Declarations>

                  </parsley:Objects>
Configuration and Initialization

       • Telling the IOC Container which classes it
         should manage
   1   • MXML, XML, AS.

       • Configure DI or Messaging for each
         individual class
   2   • MXML, XML, Metadata tags
public class GetUsersCommand {
GetUsersCommand.as
                         [Inject]
                         public var service:IUsersService;

                         [Inject(id="userModel")]
                         public var model:Model;

                         public function execute():AsyncToken {
                            return service.getUsers();
                         }

                         public function result(users:ArrayCollection):void {
                            model.users = users;
                         }
                     }




                     public class UsersView extends SkinnableComponent {
UserView.as
                         [Inject]
                         public var model:Model;

                         [Publish(objectId="selectedUser")]
                         [Bindable]
                         public var seletedUser:User;

                         [MessageHandler(selector="user")]
                         public function externalUserSelection(msg:SelectMessage):void {
                            //do something
                         }
                     }
Configuration and Initialization

       • Telling the IOC Container which classes it
         should manage.
   1   • MXML, XML, AS.

       • Configure DI or Messaging for each
         individual class
   2   • MXML, XML, Metadata tags



       • Initialize IOC Container
   3
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
You can use one big          xmlns:s="library://ns.adobe.com/flex/spark"
configuration file           xmlns:mx="library://ns.adobe.com/flex/mx"
                             xmlns:parsley="http://www.spicefactory.org/parsley"

                             <fx:Declarations>
                                <parsley:ContextBuilder config="{UserConfig}"/>
                             </fx:Declarations>
                          </s:Application>


                          <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
Or several files with        xmlns:s="library://ns.adobe.com/flex/spark"
separated configuration      xmlns:mx="library://ns.adobe.com/flex/mx"
                             xmlns:parsley="http://www.spicefactory.org/parsley"

                             <fx:Declarations>
                                <parsley:ContextBuilder>
                                   <parsley:FlexConfig type="{UserConfig}"/>
                                   <parsley:FlexConfig type="{ServiceConfig}"/>
                                   <parsley:FlexConfig type="{MockServiceConfig}"/>
                               </parsley:ContextBuilder
                          </fx:Declarations>
                          </s:Application>



                          ContextBuilder.newBuilder()
Configuration DSL           .config(FlexConfig.forClass(UserConfig))
                            .config(FlexConfig.forClass(ServiceConfig))
                            .config(XmlConfig.forFile("logging.xml"))
                            .build();
Decoupled Bindings
[Publish]
[Subscribe]
[PublishSubscribe]




• This feature is much more dynamic than Dependency Injection.
• It is really more the decoupled equivalent of the typical usage of Flex Bindings.
• The published object does not even have to be a container managed object.
Decoupled Bindings
ActionScript Examples
[Bindable]
[Publish(objectId="selectedUser")]
public var selectedUser:User;

[Subscribe(scope="window")]
public var selectedUser:User;                                             uses Local
[Bindable]
                                                                        SharedObjects
[PublishSubscribe(persistent="true", objectId="selectedUserId")]
public var selectedUserId:int;



MXML Example
<parsley:View type="{UsersView}">
   <parsley:Publish property="selectedUser“ objectId="selectedUser"/>
</parsley:View>
Messaging
[ManagedEvents]
[MessageDispatcher]
[MessageHandler]
[MessageBinding]
[MessageError]




• The exchange messages between objects in a fully decoupled manner (sender
  and the receiver do not have to know each other)
• Messaging Framework is generic, it does not impose a particular usage style
ActionScript Examples
[Event(name="userSelected",type="com.xyz.UserSelectedEvent")]        UserSelectedEvent.as
[ManagedEvents("userSelected, somethingSelected")]
public class UsersView extends SkinnableComponent {                  Event based class
    private function handleUserSelect(user:User):void {
       dispatchEvent(new UserSelectedEvent("userSelected", user));
    }
}

public class UsersView extends SkinnableComponent {
                                                                     UserSeletedMessage.as
    [MessageDispatcher]                                              Simple class
    public var dispatcher:Function;

    private function handleUserSelect(user:User):void {
       dispatcher(new UserSeletedMessage(user));
    }
}



[MessageHandler(type="com.xyz.UserSelectedEvent", messageProperties="user, role“)]
public function handleUserSelect(user:User, role:String):void {
}


[MessageBinding(messageProperty="user", type="com.xyz.UserSelectedEvent")]
public var user:User;
Object Lifecycle
[Init]
[Destroy]

                        Lifecycle phases
      preConfigure   preInit   postInit    preDestroy   postDestroy
Object Lifecycle
[Init]
[Destroy]

                                   Lifecycle phases
        preConfigure            preInit   postInit       preDestroy      postDestroy


The methods marked with [Init] get invoked after the object has been instantiated and all
injections have been processed.
[Init]
public function init():void {
   //
}


The methods marked with [Destroy] get invoked after the Context instance they belong
to has been destroyed with Context.destroy() or when the object was removed from
the Context.
[Destroy]
public function destroy():void {
   //
}
Managed Commands
•   Dynamically add a command to a Context only for the time it executes
•   Declarative way to configure Commands
•   Grouping commands (parallel, sequence, flow)
•   Map command to message
Managed Commands
[CommandResult]                   <parsley:MapCommand type="{GetUserProfileCommand}"/>
[CommandError]
                                  public class GetUserProfileCommand {
[CommandComplete]
[CommandStatus]                       [Inject("userService")]
                                      public var service:RemoteObject;

                                      public function execute(msg:GetUserMessage):AsyncToken {
                                         return service.getUserProfile(msg.userId);
                                      }

                                      public function result(profile:Profile):void {
                                         //
                                      }
                                  }

 [CommandResult]
 public function profileResult(profile:Profile, message:GetUserMessage):void {

 [CommandError]
 public function handleResult(fault:FaultEvent, trigger:GetUserMessage):void {



[Bindable]
[CommandStatus(type="com.xyz.GetUserMessage")]
public var isGettingProfile:Boolean;

<s:Button label="GetProfile" enabled="{isGettingProfile}" click="..." />
Managed Commands
 Declaring Groups in MXML
<parsley:MapCommand messageType="{FindUserMessage}">
   <parsley:CommandSequence>
      <parsley:Command type="{GetUsersCommand}"/>
      <parsley:Command type="{FindUserCommand}"/>
   </parsley:CommandSequence>
</parsley:MapCommand>


<parsley:MapCommand messageType="{FindUserMessage}">
   <parsley:ParallelCommands>
      <parsley:Command type="{FindUserCommand}"/>
      <parsley:Command type="{OutputDataComand}"/>
   </parsley:ParallelCommands>
</parsley:MapCommand>
Building MVC Architectures
Custom Scopes
Custom Scopes
Default scope is global

<parsley:ContextBuilder>                                     Add new “window” scope
   <parsley:FlexConfig type="{UserConfig}"/>
   <parsley:FlexConfig type="{ServiceConfig}"/>
   <parsley:Scope name="window" inherited="true"/>           Change default scope to local.
   <parsley:MessageSettings defaultReceiverScope="local"/>
</parsley:ContextBuilder>




Actionscript Examples
[ManagedEvents("add, remove", scope=“global")]

[MessageDispatcher(scope="local")]
public var dispatcher:Function;

[MessageHandler(selector="add", scope="local")]
public function save (event:UdpateUser):void {

[Subscribe(objectId="selectedUser", scope="window")]
public var selectedUser:User;
Localization
Usual using with flex binding
<s:Label text="{resourceManager.getString('resources', ‘user.profile')}"/>




It is useful for properties of objects managed by the IOC Container
[ResourceBinding(bundle="resources", key="user.profile")]
public var message:String;




MXML Example
<parsley:View type="{ProfileView}">
   <parsley:ResourceBinding property="header" bundle="resources" key="user.profile" />
</parsley:View>
Configuration Properties
       project.properties
       dev_url = http://www.dev.xyz.com
       prod_url = http://www.prod.xyx.com
       version = 1.0.0


Property File compiled into the Application
<fx:Declarations>
   <fx:String id="properties" source="project.properties" />
</fx:Declarations>

<parsley:ContextBuilder
   <parsley:PropertiesString source="{properties}"/>
</parsley:ContextBuilder>


External Property File
<parsley:ContextBuilder
   <parsley:PropertiesFile file="project.properties" />
</parsley:ContextBuilder>


 Using Properties in MXML Configuration
<parsley:Object type="{Config}">
   <parsley:Property name="dev" value="{properties.dev_url}" />
   <parsley:Property name="prod" value="{properties.prod_url}" />
   <parsley:Property name="version" value="{properties.version}" />
</parsley:Object>
Conclusion
Questions?
Understanding




                             Information

Weitere ähnliche Inhalte

Was ist angesagt?

Serialization & De-serialization in Java
Serialization & De-serialization in JavaSerialization & De-serialization in Java
Serialization & De-serialization in JavaInnovationM
 
Core java interview questions
Core java interview questionsCore java interview questions
Core java interview questionsRohit Singh
 
Packages and inbuilt classes of java
Packages and inbuilt classes of javaPackages and inbuilt classes of java
Packages and inbuilt classes of javakamal kotecha
 
Desing Patterns Summary - by Jim Fawcett
Desing Patterns Summary - by Jim FawcettDesing Patterns Summary - by Jim Fawcett
Desing Patterns Summary - by Jim FawcettDareen Alhiyari
 
Java Annotation Processing: A Beginner Walkthrough
Java Annotation Processing: A Beginner WalkthroughJava Annotation Processing: A Beginner Walkthrough
Java Annotation Processing: A Beginner WalkthroughMahfuz Islam Bhuiyan
 
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application ArchitectureMark Trostler
 
Introduction to Robotlegs 2
Introduction to Robotlegs 2Introduction to Robotlegs 2
Introduction to Robotlegs 2Justin J. Moses
 
JavaFX Dependency Injection with FxContainer
JavaFX Dependency Injection with FxContainerJavaFX Dependency Injection with FxContainer
JavaFX Dependency Injection with FxContainerSrikanth Shenoy
 
Java Beans Unit 4(part 2)
Java Beans Unit 4(part 2)Java Beans Unit 4(part 2)
Java Beans Unit 4(part 2)SURBHI SAROHA
 
Hibernate Interview Questions
Hibernate Interview QuestionsHibernate Interview Questions
Hibernate Interview QuestionsSyed Shahul
 

Was ist angesagt? (20)

Devoxx 2012 (v2)
Devoxx 2012 (v2)Devoxx 2012 (v2)
Devoxx 2012 (v2)
 
Serialization & De-serialization in Java
Serialization & De-serialization in JavaSerialization & De-serialization in Java
Serialization & De-serialization in Java
 
02 basic java programming and operators
02 basic java programming and operators02 basic java programming and operators
02 basic java programming and operators
 
Java Beans
Java BeansJava Beans
Java Beans
 
ExtJs Basic Part-1
ExtJs Basic Part-1ExtJs Basic Part-1
ExtJs Basic Part-1
 
Core java interview questions
Core java interview questionsCore java interview questions
Core java interview questions
 
Packages and inbuilt classes of java
Packages and inbuilt classes of javaPackages and inbuilt classes of java
Packages and inbuilt classes of java
 
Java basic
Java basicJava basic
Java basic
 
Best interview questions
Best interview questionsBest interview questions
Best interview questions
 
Spring boot
Spring bootSpring boot
Spring boot
 
Desing Patterns Summary - by Jim Fawcett
Desing Patterns Summary - by Jim FawcettDesing Patterns Summary - by Jim Fawcett
Desing Patterns Summary - by Jim Fawcett
 
Java Annotation Processing: A Beginner Walkthrough
Java Annotation Processing: A Beginner WalkthroughJava Annotation Processing: A Beginner Walkthrough
Java Annotation Processing: A Beginner Walkthrough
 
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application Architecture
 
Introduction to Robotlegs 2
Introduction to Robotlegs 2Introduction to Robotlegs 2
Introduction to Robotlegs 2
 
JavaFX Dependency Injection with FxContainer
JavaFX Dependency Injection with FxContainerJavaFX Dependency Injection with FxContainer
JavaFX Dependency Injection with FxContainer
 
Java Beans Unit 4(part 2)
Java Beans Unit 4(part 2)Java Beans Unit 4(part 2)
Java Beans Unit 4(part 2)
 
Advance Java
Advance JavaAdvance Java
Advance Java
 
Core java
Core javaCore java
Core java
 
Technical Interview
Technical InterviewTechnical Interview
Technical Interview
 
Hibernate Interview Questions
Hibernate Interview QuestionsHibernate Interview Questions
Hibernate Interview Questions
 

Ähnlich wie Parsley & Flex

Inversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionInversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionDinesh Sharma
 
Pointer to implementation idiom
Pointer to implementation idiomPointer to implementation idiom
Pointer to implementation idiomDimitrios Platis
 
SOLID & IoC Principles
SOLID & IoC PrinciplesSOLID & IoC Principles
SOLID & IoC PrinciplesPavlo Hodysh
 
Application Frameworks: The new kids on the block
Application Frameworks: The new kids on the blockApplication Frameworks: The new kids on the block
Application Frameworks: The new kids on the blockRichard Lord
 
Android architecture
Android architecture Android architecture
Android architecture Trong-An Bui
 
Java design patterns
Java design patternsJava design patterns
Java design patternsShawn Brito
 
Building maintainable app #droidconzg
Building maintainable app #droidconzgBuilding maintainable app #droidconzg
Building maintainable app #droidconzgKristijan Jurković
 
Architecting ActionScript 3 applications using PureMVC
Architecting ActionScript 3 applications using PureMVCArchitecting ActionScript 3 applications using PureMVC
Architecting ActionScript 3 applications using PureMVCmarcocasario
 
Design pattern proxy介紹 20130805
Design pattern proxy介紹 20130805Design pattern proxy介紹 20130805
Design pattern proxy介紹 20130805LearningTech
 
Design pattern proxy介紹 20130805
Design pattern proxy介紹 20130805Design pattern proxy介紹 20130805
Design pattern proxy介紹 20130805LearningTech
 
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusMicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusEmily Jiang
 
WPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaWPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaRainer Stropek
 
Java programming concept
Java programming conceptJava programming concept
Java programming conceptSanjay Gunjal
 
OpenWebBeans and DeltaSpike at ApacheCon
OpenWebBeans and DeltaSpike at ApacheConOpenWebBeans and DeltaSpike at ApacheCon
OpenWebBeans and DeltaSpike at ApacheConos890
 
Introduction to design_patterns
Introduction to design_patternsIntroduction to design_patterns
Introduction to design_patternsamitarcade
 

Ähnlich wie Parsley & Flex (20)

Dependency injection in iOS
Dependency injection in iOSDependency injection in iOS
Dependency injection in iOS
 
Inversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionInversion of Control and Dependency Injection
Inversion of Control and Dependency Injection
 
Pointer to implementation idiom
Pointer to implementation idiomPointer to implementation idiom
Pointer to implementation idiom
 
SOLID & IoC Principles
SOLID & IoC PrinciplesSOLID & IoC Principles
SOLID & IoC Principles
 
Application Frameworks: The new kids on the block
Application Frameworks: The new kids on the blockApplication Frameworks: The new kids on the block
Application Frameworks: The new kids on the block
 
Android architecture
Android architecture Android architecture
Android architecture
 
Java design patterns
Java design patternsJava design patterns
Java design patterns
 
Building maintainable app #droidconzg
Building maintainable app #droidconzgBuilding maintainable app #droidconzg
Building maintainable app #droidconzg
 
Architecting ActionScript 3 applications using PureMVC
Architecting ActionScript 3 applications using PureMVCArchitecting ActionScript 3 applications using PureMVC
Architecting ActionScript 3 applications using PureMVC
 
Rcp by example
Rcp by exampleRcp by example
Rcp by example
 
Building maintainable app
Building maintainable appBuilding maintainable app
Building maintainable app
 
Design pattern proxy介紹 20130805
Design pattern proxy介紹 20130805Design pattern proxy介紹 20130805
Design pattern proxy介紹 20130805
 
Design pattern proxy介紹 20130805
Design pattern proxy介紹 20130805Design pattern proxy介紹 20130805
Design pattern proxy介紹 20130805
 
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusMicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
 
WPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaWPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA Austria
 
Java programming concept
Java programming conceptJava programming concept
Java programming concept
 
OpenWebBeans and DeltaSpike at ApacheCon
OpenWebBeans and DeltaSpike at ApacheConOpenWebBeans and DeltaSpike at ApacheCon
OpenWebBeans and DeltaSpike at ApacheCon
 
Introduction to design_patterns
Introduction to design_patternsIntroduction to design_patterns
Introduction to design_patterns
 
Desiging for Modularity with Java 9
Desiging for Modularity with Java 9Desiging for Modularity with Java 9
Desiging for Modularity with Java 9
 
6976.ppt
6976.ppt6976.ppt
6976.ppt
 

Kürzlich hochgeladen

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 

Kürzlich hochgeladen (20)

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 

Parsley & Flex

  • 1. Parsley & framework for Flex/Flash/AIR Alexander Budjakov Flex Developer prideconan@gmail.com
  • 2. Parsley is all about decoupling
  • 3. Overview Parsley is Open Source, licensed under the Apache License 2.0 Written by Jens Halm First version 1.0.RC1 (2007-12-09) Last version 3.0.0 (2012-02-06) > 4 years Parsley is an Application Framework for Flex and Flash Applications built upon an IOC Container and Messaging Framework that can be used to create highly decoupled architectures.
  • 4. Features Parsley Spicelib Flexible IOC Container Command Framework Dependency Injection XML-Mapper Decoupled Bindings Reflection API Messaging Framework Logging Managed Commands Dynamic View Wiring Advanced Modularity Object Lifecycle Localization Extensibility
  • 6. Inversion of Control (IoC) Hollywood Principle: Don't call us, we'll call you. Program logic runs against abstractions such as callbacks
  • 7. IoC Example Here is the simplest possible Here are a common smells that should lead IoC component you to refactor to IoC package com { package com { public interface IMap { public class GPSNavigator implements INavigator { //methods private var map:IMap; } public function GPSNavigator() { } this.map = new UkraineMapImpl(); } package com { //other methods public class GPSNavigator implements INavigator { } private var map:IMap; } public function GPSNavigator(map:IMap) { } this.map = map; Some other smells. //other methods package com { } public class GPSNavigator implements INavigator { } private static var map:IMap = MapFactory.getMap(); public function GPSNavigator() { } //other methods } } It is hard coded Not reusable.
  • 8. IOC Container We may ask for the object from the container and the container creates the object and its dependencies <interface> EBookReader File inject creates PDFFileImpl TXTFileImpl IoC Container Parsley is a classic IOC Container. It provides support for Dependency Injection, Object Lifecycle Management and Messaging
  • 10. Dependency Injection (DI) [Inject] The core feature of any IOC Container How objects obtain references to each other
  • 11. Dependency Injection (DI) You may have these different tools
  • 12. Dependency Injection (DI) You may have these different tools OR just one tool with attachments
  • 13. Dependency Injection (DI) You may have these different tools OR just one tool with attachments This brings us to the Design Principles - Program to an interface, not an implementation
  • 14. Dependency Injection (DI) Three ways of classic DI
  • 15. Dependency Injection (DI) public class Controller { private var model:Model; public function Controller(model:Model) { Constructor Injection this.model = model; } }
  • 16. Dependency Injection (DI) public class Controller { private var model:Model; public function Controller(model:Model) { Constructor Injection this.model = model; } } public class Controller { private var _model:Model; public function set model(value:Model):void { Setter Injection _model = value; } }
  • 17. Dependency Injection (DI) public class Controller { private var model:Model; public function Controller(model:Model) { Constructor Injection this.model = model; } } public class Controller { private var _model:Model; public function set model(value:Model):void { Setter Injection _model = value; } } public interface IController { function injectModel(model:Model):void } Interface Injection public class Controller implements IController { private var model:Model; public function injectModel(model:Model):void { this.model = model; } }
  • 18. NOT Dependency Injection public class Controller { private var model:Model; public function Controller() { model = new Model(); } } public class Controller { private var model:Model; public function Controller() { model = ModelFactory.create(Model); } } public class Controller { private var model:Model; public function Controller() { model = Model.getInstance(); } }
  • 19. IoC and DI Benefits • Dependency management • Simplify the reuse of classes or components • Offers configuration flexibility • Simplify unit-testing • The "cleaner" code
  • 21. Configuration and Initialization • Telling the IOC Container which classes it should manage 1 • MXML, XML, AS
  • 22. <?xml version="1.0" encoding="utf-8"?> UserConfig.mxml <parsley:Objects xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:parsley="http://www.spicefactory.org/parsley"> // *hidden imports <fx:Declarations> <parsley:Object id="userModel" type="{Model}" lazy="true"/> <parsley:DynamicObject type="{Counter}"> <parsley:Property name="maxCount" value="100" /> </parsley:DynamicObject> <parsley:View type="{UsersView}"/> <service:MockUsersService /> <parsley:MapCommand type="{GetUsersCommand}" messageType="{GetUsersMessage}"/> </fx:Declarations> </parsley:Objects>
  • 23. Configuration and Initialization • Telling the IOC Container which classes it should manage 1 • MXML, XML, AS. • Configure DI or Messaging for each individual class 2 • MXML, XML, Metadata tags
  • 24. public class GetUsersCommand { GetUsersCommand.as [Inject] public var service:IUsersService; [Inject(id="userModel")] public var model:Model; public function execute():AsyncToken { return service.getUsers(); } public function result(users:ArrayCollection):void { model.users = users; } } public class UsersView extends SkinnableComponent { UserView.as [Inject] public var model:Model; [Publish(objectId="selectedUser")] [Bindable] public var seletedUser:User; [MessageHandler(selector="user")] public function externalUserSelection(msg:SelectMessage):void { //do something } }
  • 25. Configuration and Initialization • Telling the IOC Container which classes it should manage. 1 • MXML, XML, AS. • Configure DI or Messaging for each individual class 2 • MXML, XML, Metadata tags • Initialize IOC Container 3
  • 26. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" You can use one big xmlns:s="library://ns.adobe.com/flex/spark" configuration file xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:parsley="http://www.spicefactory.org/parsley" <fx:Declarations> <parsley:ContextBuilder config="{UserConfig}"/> </fx:Declarations> </s:Application> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" Or several files with xmlns:s="library://ns.adobe.com/flex/spark" separated configuration xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:parsley="http://www.spicefactory.org/parsley" <fx:Declarations> <parsley:ContextBuilder> <parsley:FlexConfig type="{UserConfig}"/> <parsley:FlexConfig type="{ServiceConfig}"/> <parsley:FlexConfig type="{MockServiceConfig}"/> </parsley:ContextBuilder </fx:Declarations> </s:Application> ContextBuilder.newBuilder() Configuration DSL .config(FlexConfig.forClass(UserConfig)) .config(FlexConfig.forClass(ServiceConfig)) .config(XmlConfig.forFile("logging.xml")) .build();
  • 27. Decoupled Bindings [Publish] [Subscribe] [PublishSubscribe] • This feature is much more dynamic than Dependency Injection. • It is really more the decoupled equivalent of the typical usage of Flex Bindings. • The published object does not even have to be a container managed object.
  • 28. Decoupled Bindings ActionScript Examples [Bindable] [Publish(objectId="selectedUser")] public var selectedUser:User; [Subscribe(scope="window")] public var selectedUser:User; uses Local [Bindable] SharedObjects [PublishSubscribe(persistent="true", objectId="selectedUserId")] public var selectedUserId:int; MXML Example <parsley:View type="{UsersView}"> <parsley:Publish property="selectedUser“ objectId="selectedUser"/> </parsley:View>
  • 29. Messaging [ManagedEvents] [MessageDispatcher] [MessageHandler] [MessageBinding] [MessageError] • The exchange messages between objects in a fully decoupled manner (sender and the receiver do not have to know each other) • Messaging Framework is generic, it does not impose a particular usage style
  • 30. ActionScript Examples [Event(name="userSelected",type="com.xyz.UserSelectedEvent")] UserSelectedEvent.as [ManagedEvents("userSelected, somethingSelected")] public class UsersView extends SkinnableComponent { Event based class private function handleUserSelect(user:User):void { dispatchEvent(new UserSelectedEvent("userSelected", user)); } } public class UsersView extends SkinnableComponent { UserSeletedMessage.as [MessageDispatcher] Simple class public var dispatcher:Function; private function handleUserSelect(user:User):void { dispatcher(new UserSeletedMessage(user)); } } [MessageHandler(type="com.xyz.UserSelectedEvent", messageProperties="user, role“)] public function handleUserSelect(user:User, role:String):void { } [MessageBinding(messageProperty="user", type="com.xyz.UserSelectedEvent")] public var user:User;
  • 31. Object Lifecycle [Init] [Destroy] Lifecycle phases preConfigure preInit postInit preDestroy postDestroy
  • 32. Object Lifecycle [Init] [Destroy] Lifecycle phases preConfigure preInit postInit preDestroy postDestroy The methods marked with [Init] get invoked after the object has been instantiated and all injections have been processed. [Init] public function init():void { // } The methods marked with [Destroy] get invoked after the Context instance they belong to has been destroyed with Context.destroy() or when the object was removed from the Context. [Destroy] public function destroy():void { // }
  • 33. Managed Commands • Dynamically add a command to a Context only for the time it executes • Declarative way to configure Commands • Grouping commands (parallel, sequence, flow) • Map command to message
  • 34. Managed Commands [CommandResult] <parsley:MapCommand type="{GetUserProfileCommand}"/> [CommandError] public class GetUserProfileCommand { [CommandComplete] [CommandStatus] [Inject("userService")] public var service:RemoteObject; public function execute(msg:GetUserMessage):AsyncToken { return service.getUserProfile(msg.userId); } public function result(profile:Profile):void { // } } [CommandResult] public function profileResult(profile:Profile, message:GetUserMessage):void { [CommandError] public function handleResult(fault:FaultEvent, trigger:GetUserMessage):void { [Bindable] [CommandStatus(type="com.xyz.GetUserMessage")] public var isGettingProfile:Boolean; <s:Button label="GetProfile" enabled="{isGettingProfile}" click="..." />
  • 35. Managed Commands Declaring Groups in MXML <parsley:MapCommand messageType="{FindUserMessage}"> <parsley:CommandSequence> <parsley:Command type="{GetUsersCommand}"/> <parsley:Command type="{FindUserCommand}"/> </parsley:CommandSequence> </parsley:MapCommand> <parsley:MapCommand messageType="{FindUserMessage}"> <parsley:ParallelCommands> <parsley:Command type="{FindUserCommand}"/> <parsley:Command type="{OutputDataComand}"/> </parsley:ParallelCommands> </parsley:MapCommand>
  • 38. Custom Scopes Default scope is global <parsley:ContextBuilder> Add new “window” scope <parsley:FlexConfig type="{UserConfig}"/> <parsley:FlexConfig type="{ServiceConfig}"/> <parsley:Scope name="window" inherited="true"/> Change default scope to local. <parsley:MessageSettings defaultReceiverScope="local"/> </parsley:ContextBuilder> Actionscript Examples [ManagedEvents("add, remove", scope=“global")] [MessageDispatcher(scope="local")] public var dispatcher:Function; [MessageHandler(selector="add", scope="local")] public function save (event:UdpateUser):void { [Subscribe(objectId="selectedUser", scope="window")] public var selectedUser:User;
  • 39. Localization Usual using with flex binding <s:Label text="{resourceManager.getString('resources', ‘user.profile')}"/> It is useful for properties of objects managed by the IOC Container [ResourceBinding(bundle="resources", key="user.profile")] public var message:String; MXML Example <parsley:View type="{ProfileView}"> <parsley:ResourceBinding property="header" bundle="resources" key="user.profile" /> </parsley:View>
  • 40. Configuration Properties project.properties dev_url = http://www.dev.xyz.com prod_url = http://www.prod.xyx.com version = 1.0.0 Property File compiled into the Application <fx:Declarations> <fx:String id="properties" source="project.properties" /> </fx:Declarations> <parsley:ContextBuilder <parsley:PropertiesString source="{properties}"/> </parsley:ContextBuilder> External Property File <parsley:ContextBuilder <parsley:PropertiesFile file="project.properties" /> </parsley:ContextBuilder> Using Properties in MXML Configuration <parsley:Object type="{Config}"> <parsley:Property name="dev" value="{properties.dev_url}" /> <parsley:Property name="prod" value="{properties.prod_url}" /> <parsley:Property name="version" value="{properties.version}" /> </parsley:Object>