Making your managed package extensible with Apex Plugins


Published on

Apex-driven processing in packaged solutions is becoming more and more complex on the platform these days. As an ISV, it is not always enough for your customers to create triggers or add their own logic around your custom objects to meet their unique requirements. Sometimes they simply want to effect or steer the existing calculations or data manipulation going on within the managed package. Join us to learn a pattern and approach that can be used to expose a plugin interface to your managed packages by using Apex Interfaces and the new Type.forName / Type.newInstance features.

Sample code available from

Published in: Technology
  • Cool, Good stuff
    Are you sure you want to  Yes  No
    Your message goes here
  • Update December 2013 (Slide 11): Implement fix for Salesforce Winter 13 change in behaviour. Issue:
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Plugin is an established design pattern uses a number of design patterns published in Martin Fowler, Patterns of Enterprise Application Architecture Andy’ Fawcett’s session: Applying Enterprise Application Design Patterns on
  • Visualforce UIs - +fieldsets
  • Update December 2013: Implement fix for Salesforce Winter 13 change in behaviour. Issue:
  • In Winter ‘13 we will not need to make this class global
  • Assisted: discover candidates from which a user selects and persists in cust setting
  • Extend / override - responsibility of package or plugin?
  • Chatter wall for this session
  • Making your managed package extensible with Apex Plugins

    1. 1. Making your managed packageextensible with Apex PluginsStephen Willcock,, Director of Product Innovation@stephenwillcock
    2. 2. Safe harbor Safe harbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of, inc. could differ materially from the results expressed or implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of intellectual property and other litigation, risks associated with possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of, inc. is included in our annual report on Form 10-Q for the most recent fiscal quarter ended July 31, 2012. This documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site. Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available., inc. assumes no obligation and does not intend to update these forward- looking statements.
    3. 3. All about
    4. 4. Stephen WillcockDirector, Product Innovation@stephenwillcock
    5. 5. What is an Apex Plugin?An Apex plugin for a managed package is an external class that iscalled from within the packageThe package has no dependency on the class, which isinstantiated dynamically by runtime configuration
    6. 6. Why use a Plugin?Plugins allow changes to the execution of packaged Apexprocesses Managed Package Runtime Configuration: Runtime Configuration: Opportunity Adjuster Use “CustomAdjuster” for Use “CustomAdjuster” for Adjusting Opportunities Adjusting Opportunities CustomAdjuster plugin Call the plugin
    7. 7. Where to use a Plugin?  Visualforce UIs  Triggers  @RemoteAction methods  Apex APIs  Batch Apex  Generic plugins for common calculations  “Apex Validation Rules”  “Apex Workflow Rules”
    8. 8. Example use caseApplication for adjusting Opportunity valuesVisualforce UICustomizable adjustment and validation
    9. 9. Implementation Managed Package public class AdjustOpportunityController global class Plugin Runtime Configuration: Runtime Configuration: Use “CustomAdjuster” for Use “CustomAdjuster” for public static IAdjustOpportunities Adjusting Opportunities Adjusting Opportunities getInstanceIAdjustOpportunities() global class CustomAdjuster global interface IAdjustOpportunities implements IAdjustOpportunities
    10. 10. Implementation global class Plugin Packaged Codeglobal interface IAdjustOpportunities{ void adjust(Opportunity opportunity, List<OpportunityLineItem> lineItems, Decimal proportion);}
    11. 11. Implementation global class Plugin Packaged Code
    12. 12. Implementation global class Plugin Packaged Codepublic static Plugin.IAdjustOpportunities getInstanceIAdjustOpportunities(){ Object result = getInstance (IAdjustOpportunities); return (Plugin.IAdjustOpportunities) (result == null ? new DefaultAdjustOpportunities() : result);}
    13. 13. Implementation global class Plugin Packaged Code
    14. 14. Implementation global class Plugin Packaged Code // do the adjustment here... for(OpportunityLineItem item : opportunityLineItems) item.UnitPrice = item.UnitPrice + (item.UnitPrice * adjustmentProportion); opportunity.Amount = opportunity.Amount + (opportunity.Amount * adjustmentProportion);
    15. 15. Implementation public with sharing class Packaged AdjustOpportunityController Codevoid adjust(){ Plugin.IAdjustOpportunities adjuster = Plugin.getInstanceIAdjustOpportunities(); adjuster.adjust(getOpportunity(), getOpportunityLines(), getAdjustmentProportion());}
    16. 16. PluginImplementation global class CustomAdjuster Code
    17. 17. Configuration optionsManual custom settingsDiscovery by name patternAssisted custom settings
    18. 18. Plug-and-play Demo
    19. 19. ConsiderationsConsider the lifecycle / context of a plugin instance  Triggers: bulk usage / before and after triggers  Instantiation within a loop / discarding instances  Visualforce viewstateInterface granularityExtend or override?Only default plugin constructors are usedVersioning of global interfaces by name
    20. 20. UnplugResources  Sample code and package installation URL available from  Martin Fowler, Patterns of Enterprise Application Architecture: • Plugin • Separated Interface  @stephenwillcockQuestions?