diff --git a/xpcom/doc/xpcom-component-registration.html b/xpcom/doc/xpcom-component-registration.html new file mode 100644 index 000000000000..c97fe1feae86 --- /dev/null +++ b/xpcom/doc/xpcom-component-registration.html @@ -0,0 +1,226 @@ + + + + + + + XPCOM Dynamic Component Registration + + + +
+

+XPCOM Dynamic Component Registration

+ +
Suresh Duddi <dp@netscape.com> +
+ +

Dynamic object registration in XPCOM is achieved by interaction of the +following components: +

+The registration mechanism for XPCOM components is similar in many ways +to that of COM. The XPCOM component dlls will have the opportunity to register +themselves with the registry. The exact time of installation would be either +at install time or as a result of autodetection by the Repository +Manager at runtime. +
  +

+The Registry: XPCOM Hierarchy

+XPCOM uses the nsRegistry to store mappings between CLSIDs and their implementations. +The Registry provides persistent storage of hierarchical keys and name-value +pairs associated with each key. Each key also keeps a default value. +

XPCOM will use the following registry hierarchy: +

ROOTKEY_COMMON +
    Classes +
        CLSID +
            +"CLSID-string"    "class name" +
               +ProgID        "component.class.version" +
               +InprocServer  "full-path-name" +
                    +LastModTimeStamp*   time-value +
                   +FileSize*          +nbytes +
    "component.class.version"    +"class name" +
        CLSID        +"CLSID-string"
+ +


* Automatically +added by the Repository +
  +

+The Repository: +Object instance creation

+All object creation happens via The Repository. nsIRepository::CreateInstance() +will be the primary way of creation of object instances. The steps in instantiation +of an object that implements the IID interface and of class CLSID is as +follows: +
    +
  1. +The CLSID of the component that would need to create the object instance +is identified.
  2. + +
      If the input to nsIRepository::CreateInstance() is a CLSID, +then there is no figuring out. If the input is a ProgID string, it uses +nsIRepository::ProgIDToCLSID() +to convert the ProgID string passed into it to convert to the CLSID.
    + +
  3. +Load the dll associated with the CLSID after consulting the Registry
  4. + +
  5. +Instantiate the class factory by calling a globally exported dll function +NSGetFactory(). +This returns an instance of the class factory that implements the nsIFactory +interface.
  6. + +
  7. +The actual object creation is delegated to this nsIFactory instance +with a call to nsIFactory::CreateInstance().
  8. +
+ +

+The Service Manager

+All globally created system services are available via the nsIServiceManager, +including the nsIRepository and nsIRegistry. Although +the nsIServiceManager uses the Registry and Repository in the +creation and maintenance of other services, the circular dependency is +broken by not letting the nsIServiceManager create the nsIRepository +and nsIRegistry instance and registering them specially with the +nsIServiceManager. +The nsIServiceManager is passed into NSGetFactory() for assisting the DLL +in the Factory creation process. +

+Component Registration

+Either at installation time of the Component or at times when the XPCOM +library autodetect new/changed dlls, component registration is activated. +The autodetection happens at startup time of the navigator or via a javascript +trigger navigator.repository.autodetect(). The steps in component +registration would be: +
    +
  1. +The dll is loaded
  2. + +
  3. +The component is allowed to self register by a call to a globally exported +dll function NSRegisterSelf(). The nsIServiceManager +and the fullpath of the dll are passed in to assist in the registration +process. The dll is expected to create/modify its entries in the Registry +according to the guidelines of the XPCOM +hierarchy in the registry. nsIRepository, which can be queried +from the nsIServiceManager, has useful registration functions +that would easen the process.
  4. + +
  5. +The dll is unloaded
  6. +
+ +

+Autodetection of Components

+Autodetection of changed dlls happened by storing the dll's last modified +time and its size in the Registry automatically. If either the last modified +time stamp or the filesize differs from that stored in the Registry for +the dll, re-registration takes place. Before re-registration, the existing +instances of the objects created by the classes in the dll are not freed +because the nsIRepository has no list of them. The NSCanUnload() +will be called with input parameter force set to true. +The dll has to prepare for getting unloaded. After this call returns, the +dll will be unloaded if the return value is true. If the +dll detects that it cannot properly prepare for unloading, then it can +return false. XPCOM will not let the re-registration of the modified +dll proceed in this case. There is nothing much that XPCOM library can +do to salvage this situation other than warning the user of possible instability +and advice a restart upon which the re-registration will happen. +
  +

+How will all this help me

+For Component Developers: + +For Component Users: +
+
  • +No more hacking in calls to nsIRepository::RegisterFactory()
  • + +
  • +No need to know the CLSID of components that you want to instantiate. Component +creation can happen like this
  • + +
    nsIRepository::CreateInstance("Gecko.LayoutEngine.1", NULL, +domIID, &result); +
    instead of +
    nsIRepository::CreateInstance(RAPTOR_CLSID, NULL, domIID, +&result); +

    Another example : To create a button instance that supports IWidget +interface, +
    nsIRepository::CreateInstance("xpfe.button.1", NULL, nsWidgetIID, +&result);

    + +

    +Issues

    + + + +
    +
    Last Modified: 28 Jan 1998 +
    Feedback to: netscape.public.mozilla.xpcom + +