Ecto Model Support Functions Extension

综合编程 Vinsol

The post belongs to NectarCommerce and Extension Framework Awareness
Series


  1. NectarCommerce Vision

  2. Extension Framework Game Plan

  3. Introduction to Metaprogramming

  4. Ecto Model Schema Extension
  5. Ecto Model Support Functions Extension
  6. Phoenix Router Extension
  7. Phoenix View Extension
  8. Running Multiple Elixir Apps Together
  9. Extension Approach Explained
  10. Developer Experience and Workflow developing Favorite Product Extension
  11. Developer Experience and Workflow testing Favorite Product Extension

What will be NectarCommerce

Off-the-shelf Opensource E-commerce application for building an online store.

Provides an Extension Framework to support features not included in core as extensions.

Strives for unobtrusive parallel development of NectarCommerce and Extensions

NectarCommerce is committed to providing a ready-to-use e-commerce solution but the definition of 100% is different under different business domains. It aims to solve common use-cases as part of the project and relying on extension framework to tap the rest.

Ecto Model Support Functions Extension

Note:This blog post is very similar to Ecto Model Schema Extension
, you can wish to jump straight to

Why

We want to allow Extensions to add support functions to existing Nectar Models without changing the Nectar Models.

How

Minimum three parts are needed to create & use an extension effectively:

  • Library Code
  • Service Code
  • Consumer Code

An extension and its use with Nectar can be viewed as Producer / Consumer relationship bound by a communication protocol.

Extensionwhich wants to add a function, say fn_from_outside to Nectar Product Model, is a Producer (Service Code)
.

Nectar Modelis a Consumer (Consumer Code)
allowing the new function additions through a communication protocol (Library Code)

Let’s begin the journey of incremental changes to bring consumer, service and library code into existence starting from a simple use-case of adding a function, say fn_from_outside
, to Nectar Product.

Note: Please refer Introduction to Metaprogramming
for more information on Metaprogramming in Elixir

  1. A straightforward way to add a function, say fn_from_outside, to Nectar Product would be adding it directly in Nectar.Product, but it requires change in Nectar source. Let’s move to the next step for avoiding any modification to Nectar.Product

  2. Like, other extensions, adding a function to Nectar Model and importing it would not solve our purpose of calling function as Nectar.Product.fn_from_outside
    .

    import
    makes the
    functions available inside the module and can only be called inside Module and not from outside like Nectar.Product.fn_from_outside

    As expected, Elixir is well-aware of the use-case and provides @before_compile
    hook to inject functions in Modules as if their own and can be called as Nectar.Product.fn_from_outside
    , see full version here
    . See Nectar.ExtendProduct example below on how to use it.

  3. Now, with @before_compile Nectar.ExtendProduct
    in place, we can work towards providing a way to register the new functions, see full version here
    . Please check the usage of Module attributes for same below.

  4. Earlier, Module.put_attribute was used multiple times to define many functions whereas now we wrapped it in an anonymous function to encapsulate the collection of function additions through a simple and consistent interface, see full version here
    . There can be multiple extensions used for different functionality and hence many functions need to be registered and defined

  5. Now, Nectar.ExtendProduct is getting cluttered with ancillary method definitions. Let’s move it out to another module and use it, see full version here

  6. Let’s further reduce the boilerplate of registering method_block module attribute and importing include_method method definition with __using__
    callback, see full version here

  7. Reference of method_block Module attribute is scattered across Nectar.ExtendProduct and Nectar.ModelExtension so let’s move it out to Nectar.ModelExtension to consolidate the usage via __before_compile__
    and definition together, see full version here

  8. Now, Nectar.ExtendProduct
    has __using__
    macro definition, which can also be moved to Nectar.ModelExtension
    to just have new method defintions in Nectar.ExtendProduct
    , see full version here

  9. With above changes, it’s now possible to define any number of functions, see full version here
    . Also, any number of functions can now be added using include_method
    in Nectar.ExtendProduct without making any changes to Nectar.Product.

Check all the revisions at once, here


Now, in the final version
, you can easily find the three components, consumer, service and library code
, as desired in extensible system

Our aim with these posts is to start a dialog with the Elixir community on validity and technical soundness of our approach. We would really appreciate your feedback and reviews, and any ideas/suggestions/pull requests for improvements to our current implementation or entirely different and better way to do things to achieve the goals we have set out for NectarCommerce.

Enjoy the Elixir potion !!

稿源:Vinsol (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 综合编程 » Ecto Model Support Functions Extension

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录