You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2018/05/22 19:07:13 UTC

celix git commit: CELIX-426: Refactor C++ BundleContext using a pimpl approach to hide details

Repository: celix
Updated Branches:
  refs/heads/feature/CELIX-426-cxx-api e7cfed4cb -> d8ebc4ab3


CELIX-426: Refactor C++ BundleContext using a pimpl approach to hide details


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/d8ebc4ab
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/d8ebc4ab
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/d8ebc4ab

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: d8ebc4ab3afc75530bcb307f35abdcf0852c19dc
Parents: e7cfed4
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue May 22 21:06:40 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue May 22 21:06:40 2018 +0200

----------------------------------------------------------------------
 .../bundle_example_cxx/src/BundleActivator.cc   |   1 -
 framework/include/celix/BundleActivator.h       |   2 +-
 framework/include/celix/BundleContext.h         |  56 +--
 .../include/celix/impl/BundleContextImpl.h      | 460 +++++++++----------
 framework/include/celix/impl/FrameworkImpl.h    |   2 +-
 framework/include/celix_bundle_context.h        |   1 +
 6 files changed, 262 insertions(+), 260 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/d8ebc4ab/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
index a472b06..741ce60 100644
--- a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
+++ b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
@@ -19,7 +19,6 @@
 
 #include <iostream>
 #include "celix/BundleActivator.h"
-
 namespace {
     class BundleActivator  {
     public:

http://git-wip-us.apache.org/repos/asf/celix/blob/d8ebc4ab/framework/include/celix/BundleActivator.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/BundleActivator.h b/framework/include/celix/BundleActivator.h
index d4b98b6..448f75b 100644
--- a/framework/include/celix/BundleActivator.h
+++ b/framework/include/celix/BundleActivator.h
@@ -46,7 +46,7 @@ namespace celix {
     public:
         BundleActivatorAdapter(bundle_context_t *c_ctx) {
             this->fw = std::unique_ptr<celix::Framework>{new celix::impl::FrameworkImpl{c_ctx}}; \
-            this->ctx = std::unique_ptr<celix::BundleContext>{new celix::impl::BundleContextImpl{c_ctx, *this->fw}}; \
+            this->ctx = std::unique_ptr<celix::BundleContext>{new celix::BundleContext{c_ctx, *this->fw}}; \
             this->activator = nullptr;
         }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/d8ebc4ab/framework/include/celix/BundleContext.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/BundleContext.h b/framework/include/celix/BundleContext.h
index 077f661..f5e2735 100644
--- a/framework/include/celix/BundleContext.h
+++ b/framework/include/celix/BundleContext.h
@@ -20,6 +20,7 @@
 #include <string>
 #include <vector>
 #include <functional>
+#include <memory>
 
 #include "celix/Constants.h"
 #include "celix/Properties.h"
@@ -45,6 +46,11 @@ namespace celix {
         ServiceRegistrationOptions(I& _svc, const std::string& _serviceName) : svc{&_svc}, serviceName{_serviceName} {};
         ServiceRegistrationOptions(celix::IServiceFactory<I>& _factory, const std::string& _serviceName) : factory{&_factory}, serviceName{_serviceName} {};
 
+        ServiceRegistrationOptions(const ServiceRegistrationOptions&) = delete;
+        ServiceRegistrationOptions& operator=(const ServiceRegistrationOptions&) = delete;
+        ServiceRegistrationOptions(ServiceRegistrationOptions&&) = delete;
+        ServiceRegistrationOptions& operator=(ServiceRegistrationOptions&) = delete;
+
         I *svc{nullptr};
         celix::IServiceFactory<I> *factory{nullptr};
 
@@ -127,13 +133,10 @@ namespace celix {
         std::string resourceLenSymbol{};
     };
 
-    //opaque types to forward impl details to impl header
-    struct ServiceRegistrationEntry;
-    struct ServiceTrackingEntry;
-
     class BundleContext {
     public:
-        virtual ~BundleContext(){};
+        BundleContext(celix_bundle_context_t *ctx, celix::Framework& fw); //TODO hide somehow ... friend ?
+        virtual ~BundleContext();
 
         template<typename I>
         long registerService(I *svc, const std::string &serviceName, celix::Properties props = {}) noexcept;
@@ -152,7 +155,7 @@ namespace celix {
 
         //TODO register std::function ?
 
-        virtual void unregisterService(long serviceId) noexcept = 0;
+        void unregisterService(long serviceId) noexcept;
 
 
         /**
@@ -226,10 +229,10 @@ namespace celix {
         /**
          * Note ordered by service rank.
          */
-        virtual std::vector<long> findServices(const std::string &serviceName, const std::string &versionRange = "", const std::string &filter = "", const std::string &lang = "") noexcept = 0;
+        std::vector<long> findServices(const std::string &serviceName, const std::string &versionRange = "", const std::string &filter = "", const std::string &lang = "") noexcept;
 
         //TODO also support getting int, long, unsigned int, etc??
-        virtual std::string getProperty(const std::string &key, std::string defaultValue = "") noexcept  = 0;
+        std::string getProperty(const std::string &key, std::string defaultValue = "") noexcept;
 
         //TODO options
 
@@ -246,40 +249,39 @@ namespace celix {
          *
          * Will log a error if the provided tracker id is unknown. Will silently ignore trackerId < 0.
          */
-        virtual void stopTracker(long trackerId) noexcept  = 0;
+        void stopTracker(long trackerId) noexcept;
 
-        virtual celix::Framework& getFramework() noexcept = 0;
+        celix::Framework& getFramework() noexcept;
 
-        virtual celix::Bundle& getBundle() noexcept = 0;
+        celix::Bundle& getBundle() noexcept;
 
-        virtual celix::dm::DependencyManager& getDependencyManager() noexcept  = 0;
-
-        //TODO
-        //class celix::DependencyManager; //forward declaration TODO create
-        //virtual celix::DependencyManager& getDependencyManager() const noexcept = 0;
+        celix::dm::DependencyManager& getDependencyManager() noexcept;
 
-        virtual long registerEmbeddedBundle(
+        /** TODO
+        long registerEmbeddedBundle(
                 std::string id,
                 std::function<void(celix::BundleContext& ctx)> start,
                 std::function<void(celix::BundleContext& ctx)> stop,
                 celix::Properties manifest = {},
                 bool autoStart = true
-        ) noexcept = 0;
+        ) noexcept;
 
-        virtual void registerEmbeddedBundle(const celix::BundleRegistrationOptions &opts) noexcept = 0;
+         void registerEmbeddedBundle(const celix::BundleRegistrationOptions &opts) noexcept = 0;
+        */
 
-        virtual long installBundle(const std::string &bundleLocation, bool autoStart = true) noexcept = 0;
 
-        virtual void useBundles(const std::function<void(const celix::Bundle &bnd)> &use) noexcept = 0;
 
-        virtual bool useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept = 0;
-    protected:
-        virtual long registerServiceInternal(celix::ServiceRegistrationEntry &&entry) noexcept  = 0;
+        long installBundle(const std::string &bundleLocation, bool autoStart = true) noexcept;
 
-        virtual long trackServicesInternal(celix::ServiceTrackingEntry &&entry) noexcept  = 0;
+        void useBundles(const std::function<void(const celix::Bundle &bnd)> &use) noexcept;
 
-        virtual bool useServiceInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0;
-        virtual void useServicesInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0;
+        bool useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept;
+    protected:
+        bool useServiceInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept;
+        void useServicesInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept;
+    private:
+        struct Impl;
+        std::unique_ptr<celix::BundleContext::Impl> pimpl{nullptr};
     };
 
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/d8ebc4ab/framework/include/celix/impl/BundleContextImpl.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/impl/BundleContextImpl.h b/framework/include/celix/impl/BundleContextImpl.h
index 982963a..b90c6fd 100644
--- a/framework/include/celix/impl/BundleContextImpl.h
+++ b/framework/include/celix/impl/BundleContextImpl.h
@@ -31,263 +31,263 @@
 #include "celix/dm/DependencyManager.h"
 #include "celix_service_factory.h"
 
+namespace celix {
+
+    namespace impl {
+        struct ServiceTrackingEntryFunctions {
+            std::function<void(void *)> set{};
+            std::function<void(void *, const celix::Properties &)> setWithProperties{};
+            std::function<void(void *, const celix::Properties &, const celix::Bundle &)> setWithOwner{};
+
+            std::function<void(void *)> add{};
+            std::function<void(void *, const celix::Properties &)> addWithProperties{};
+            std::function<void(void *, const celix::Properties &, const celix::Bundle &)> addWithOwner{};
+
+            std::function<void(void *)> remove{};
+            std::function<void(void *, const celix::Properties &)> removeWithProperties{};
+            std::function<void(void *, const celix::Properties &, const celix::Bundle &)> removeWithOwner{};
+        };
+
+        struct ServiceRegistrationEntry {
+            ServiceRegistrationEntry() {
+                std::memset(&this->cOpts, 0, sizeof(this->cOpts));
+                std::memset(&this->factory, 0, sizeof(this->factory));
+            }
+
+            celix_service_factory_t factory = {nullptr, nullptr, nullptr};
+            celix_service_registration_options_t cOpts = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
+        };
+
+        struct ServiceTrackingEntry {
+            celix_service_tracking_options_t cOpts{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+                                                   nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
+            std::unique_ptr<ServiceTrackingEntryFunctions> functions{nullptr};
+        };
+    }
+
+    struct BundleContext::Impl {
+        Impl(celix_bundle_context_t *_c_ctx, celix::Framework &_fw) : c_ctx(_c_ctx), fw(_fw), bnd(c_ctx), dm(c_ctx) {}
+        ~Impl() = default;
+
+        Impl(const Impl&) = delete;
+        Impl& operator=(const Impl&) = delete;
+        Impl(Impl&&) = delete;
+        Impl& operator=(Impl&&) = delete;
+
+        //initialized in ctor
+        bundle_context_t *c_ctx;
+        celix::Framework& fw;
+        celix::impl::BundleImpl bnd;
+        celix::dm::DependencyManager dm;
+
+        std::mutex mutex{};
+        std::map<long,celix::impl::ServiceTrackingEntry> trackingEntries{};
+        std::map<long,celix::impl::ServiceRegistrationEntry> registrationEntries{};
+
+        long registerServiceInternal(celix::impl::ServiceRegistrationEntry &&entry) noexcept;
+        long trackServicesInternal(celix::impl::ServiceTrackingEntry &&entry) noexcept;
+    };
+}
+
 namespace {
     static celix::Properties createFromCProps(const celix_properties_t *c_props) {
         celix::Properties result{};
         const char *key = nullptr;
-        CELIX_PROPERTIES_FOR_EACH(const_cast<celix_properties_t*>(c_props), key) {
+        CELIX_PROPERTIES_FOR_EACH(const_cast<celix_properties_t *>(c_props), key) {
             result[key] = celix_properties_get(c_props, key);
         }
         return result;
     }
-
-    struct ServiceTrackingEntryFunctions {
-        std::function<void(void *)> set{};
-        std::function<void(void *, const celix::Properties &)> setWithProperties{};
-        std::function<void(void *, const celix::Properties &, const celix::Bundle &)> setWithOwner{};
-
-        std::function<void(void *)> add{};
-        std::function<void(void *, const celix::Properties &)> addWithProperties{};
-        std::function<void(void *, const celix::Properties &, const celix::Bundle &)> addWithOwner{};
-
-        std::function<void(void *)> remove{};
-        std::function<void(void *, const celix::Properties &)> removeWithProperties{};
-        std::function<void(void *, const celix::Properties &, const celix::Bundle &)> removeWithOwner{};
-    };
 }
 
+inline celix::BundleContext::BundleContext(bundle_context_t *ctx, celix::Framework& fw) {
+    this->pimpl = std::unique_ptr<celix::BundleContext::Impl>{new celix::BundleContext::Impl(ctx, fw)};
+}
 
-namespace celix {
-
-    struct ServiceRegistrationEntry {
-        ServiceRegistrationEntry() {
-            std::memset(&this->cOpts, 0, sizeof(this->cOpts));
-            std::memset(&this->factory, 0, sizeof(this->factory));
+inline celix::BundleContext::~BundleContext() {
+    //NOTE no need to destroy the c bundle context -> done by c framework
+    {
+        //clearing service registration
+        std::lock_guard<std::mutex> lock{this->pimpl->mutex};
+        for (auto &pair : this->pimpl->registrationEntries) {
+            celix_bundleContext_unregisterService(this->pimpl->c_ctx, pair.first);
         }
-        celix_service_factory_t factory;
-        celix_service_registration_options_t cOpts;
-    };
+        this->pimpl->registrationEntries.clear();
+    }
 
-    struct ServiceTrackingEntry {
-        ServiceTrackingEntry() {
-            std::memset(&this->cOpts, 0, sizeof(this->cOpts));
+    {
+        //clearing tracker entries
+        std::lock_guard<std::mutex> lock{this->pimpl->mutex};
+        for (auto &pair : this->pimpl->trackingEntries) {
+            celix_bundleContext_stopTracker(this->pimpl->c_ctx, pair.first);
         }
-        celix_service_tracking_options_t cOpts;
-        std::unique_ptr<ServiceTrackingEntryFunctions> functions{nullptr};
-    };
+        this->pimpl->trackingEntries.clear();
+    }
 
-    namespace impl {
+    this->pimpl->c_ctx = nullptr;
+    this->pimpl = nullptr;
+}
 
-        class BundleContextImpl : public celix::BundleContext {
-        public:
-            BundleContextImpl(bundle_context_t *ctx, celix::Framework& _fw) : c_ctx(ctx), fw(_fw), bnd(c_ctx), dm(c_ctx) {}
-
-            virtual ~BundleContextImpl() {
-                //NOTE no need to destroy the c bundle context -> done by c framework
-
-                {
-                    //clearing service registration
-                    std::lock_guard<std::mutex> lock{this->mutex};
-                    for (auto &pair : this->registrationEntries) {
-                        celix_bundleContext_unregisterService(this->c_ctx, pair.first);
-                    }
-                    this->registrationEntries.clear();
-                }
-
-                {
-                    //clearing tracker entries
-                    std::lock_guard<std::mutex> lock{this->mutex};
-                    for (auto &pair : this->trackingEntries) {
-                        celix_bundleContext_stopTracker(this->c_ctx, pair.first);
-                    }
-                    this->trackingEntries.clear();
-                }
-
-                this->c_ctx = nullptr;
-            }
 
-            BundleContextImpl(const BundleContextImpl&) = delete;
-            BundleContextImpl& operator=(const BundleContextImpl&) = delete;
-            BundleContextImpl(BundleContextImpl&&) = delete;
-            BundleContextImpl& operator=(BundleContextImpl&&) = delete;
-
-            void unregisterService(long serviceId) noexcept override {
-                std::lock_guard<std::mutex> lock{this->mutex};
-                celix_bundleContext_unregisterService(this->c_ctx, serviceId);
-                auto it = this->registrationEntries.find(serviceId);
-                if (it != this->registrationEntries.end()) {
-                    this->registrationEntries.erase(it);
-                }
-            }
+inline void celix::BundleContext::unregisterService(long serviceId) noexcept {
+    std::lock_guard<std::mutex> lock{this->pimpl->mutex};
+    celix_bundleContext_unregisterService(this->pimpl->c_ctx, serviceId);
+    auto it = this->pimpl->registrationEntries.find(serviceId);
+    if (it != this->pimpl->registrationEntries.end()) {
+        this->pimpl->registrationEntries.erase(it);
+    }
+}
 
-            std::vector<long> findServices(const std::string &/*serviceName*/, const std::string &/*versionRange*/, const std::string &/*filter*/, const std::string &/*lang = ""*/) noexcept override  {
-                std::vector<long> result{};
+inline std::vector<long> celix::BundleContext::findServices(const std::string &/*serviceName*/, const std::string &/*versionRange*/, const std::string &/*filter*/, const std::string &/*lang = ""*/) noexcept {
+    std::vector<long> result{};
 //                auto use = [&result](void *, const celix::Properties &props, const celix::Bundle &) {
 //                    long id = celix::getProperty(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
 //                    if (id >= 0) {
 //                        result.push_back(id);
 //                    }
 //                };
-                //TODO useServicesWithOptions this->useServicesInternal(serviceName, versionRange, filter, use);
-                return result;
-            }
+    //TODO useServicesWithOptions this->useServicesInternal(serviceName, versionRange, filter, use);
+    return result;
+}
 
-            void stopTracker(long trackerId) noexcept override {
-                std::lock_guard<std::mutex> lock{this->mutex};
-                celix_bundleContext_stopTracker(this->c_ctx, trackerId);
-                auto it = this->trackingEntries.find(trackerId);
-                if (it != this->trackingEntries.end()) {
-                    this->trackingEntries.erase(it);
-                }
-            }
+inline void celix::BundleContext::stopTracker(long trackerId) noexcept {
+    std::lock_guard<std::mutex> lock{this->pimpl->mutex};
+    celix_bundleContext_stopTracker(this->pimpl->c_ctx, trackerId);
+    auto it = this->pimpl->trackingEntries.find(trackerId);
+    if (it != this->pimpl->trackingEntries.end()) {
+        this->pimpl->trackingEntries.erase(it);
+    }
+}
 
-            std::string getProperty(const std::string &key, std::string defaultValue) noexcept  override  {
-                const char *val = nullptr;
-                bundleContext_getPropertyWithDefault(this->c_ctx, key.c_str(), defaultValue.c_str(), &val);
-                return std::string{val};
-            }
+inline std::string celix::BundleContext::getProperty(const std::string &key, std::string defaultValue) noexcept {
+    const char *val = nullptr;
+    bundleContext_getPropertyWithDefault(this->pimpl->c_ctx, key.c_str(), defaultValue.c_str(), &val);
+    return std::string{val};
+}
 
-            bool isInvalid() const noexcept {
-                return this->c_ctx == nullptr;
-            }
 
-            long registerEmbeddedBundle(
-                    std::string /*id*/,
-                    std::function<void(celix::BundleContext & ctx)> /*start*/,
-                    std::function<void(celix::BundleContext & ctx)> /*stop*/,
-                    celix::Properties /*manifest*/,
-                    bool /*autoStart*/
-            ) noexcept override {
-                return -1; //TODO
-            };
-
-            void registerEmbeddedBundle(const celix::BundleRegistrationOptions &/*opts*/) noexcept override {
-                //TODO
+//    long celix::BundleContext::registerEmbeddedBundle(
+//            std::string /*id*/,
+//            std::function<void(celix::BundleContext & ctx)> /*start*/,
+//            std::function<void(celix::BundleContext & ctx)> /*stop*/,
+//            celix::Properties /*manifest*/,
+//            bool /*autoStart*/
+//    ) noexcept  {
+//        return -1; //TODO
+//    };
+//
+//    void registerEmbeddedBundle(const celix::BundleRegistrationOptions &/*opts*/) noexcept override {
+//        //TODO
+//    }
+
+inline long celix::BundleContext::installBundle(const std::string &bundleLocation, bool autoStart) noexcept {
+    long bndId = -1;
+    if (this->pimpl->c_ctx != nullptr) {
+        bundle_t *bnd = nullptr;
+        bundleContext_installBundle(this->pimpl->c_ctx, bundleLocation.c_str(), &bnd);
+        if (bnd != nullptr) {
+            bundle_getBundleId(bnd, &bndId);
+            if (autoStart) {
+                bundle_start(bnd);
             }
+        }
+    }
+    return bndId;
+}
 
-            long installBundle(const std::string &bundleLocation, bool autoStart) noexcept override {
-                long bndId = -1;
-                if (this->c_ctx != nullptr) {
-                    bundle_t *bnd = nullptr;
-                    bundleContext_installBundle(this->c_ctx, bundleLocation.c_str(), &bnd);
-                    if (bnd != nullptr) {
-                        bundle_getBundleId(bnd, &bndId);
-                        if (autoStart) {
-                            bundle_start(bnd);
-                        }
-                    }
-                }
-                return bndId;
-            }
 
+inline void celix::BundleContext::useBundles(const std::function<void(const celix::Bundle &bnd)> &use) noexcept {
+    auto c_use = [](void *handle, const celix_bundle_t *c_bnd) {
+        auto *func =  static_cast<std::function<void(const celix::Bundle &bnd)>*>(handle);
+        auto m_bnd = const_cast<celix_bundle_t*>(c_bnd);
+        celix::impl::BundleImpl bnd{m_bnd};
+        (*func)(bnd);
+    };
+    celix_bundleContext_useBundles(this->pimpl->c_ctx, (void*)(&use), c_use);
+}
 
-            void useBundles(const std::function<void(const celix::Bundle &bnd)> &use) noexcept override {
-                auto c_use = [](void *handle, const celix_bundle_t *c_bnd) {
-                    auto *func =  static_cast<std::function<void(const celix::Bundle &bnd)>*>(handle);
-                    auto m_bnd = const_cast<celix_bundle_t*>(c_bnd);
-                    celix::impl::BundleImpl bnd{m_bnd};
-                    (*func)(bnd);
-                };
-                celix_bundleContext_useBundles(this->c_ctx, (void*)(&use), c_use);
-            }
+inline bool celix::BundleContext::useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept {
+    auto c_use = [](void *handle, const celix_bundle_t *c_bnd) {
+        auto *func =  static_cast<std::function<void(const celix::Bundle &bnd)>*>(handle);
+        auto m_bnd = const_cast<celix_bundle_t*>(c_bnd);
+        celix::impl::BundleImpl bnd{m_bnd};
+        (*func)(bnd);
+    };
+    return celix_bundleContext_useBundle(this->pimpl->c_ctx, bundleId, (void*)(&use), c_use);
+}
 
-            bool useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept override {
-                auto c_use = [](void *handle, const celix_bundle_t *c_bnd) {
-                    auto *func =  static_cast<std::function<void(const celix::Bundle &bnd)>*>(handle);
-                    auto m_bnd = const_cast<celix_bundle_t*>(c_bnd);
-                    celix::impl::BundleImpl bnd{m_bnd};
-                    (*func)(bnd);
-                };
-                return celix_bundleContext_useBundle(this->c_ctx, bundleId, (void*)(&use), c_use);
-            }
+inline celix::Framework& celix::BundleContext::getFramework() noexcept {
+    return this->pimpl->fw;
+}
 
-            celix::Framework& getFramework() noexcept override {
-                return this->fw;
-            }
+inline celix::Bundle& celix::BundleContext::getBundle() noexcept {
+    return this->pimpl->bnd;
+};
 
-            celix::Bundle& getBundle() noexcept override {
-                return this->bnd;
-            };
+inline celix::dm::DependencyManager& celix::BundleContext::getDependencyManager() noexcept {
+    return this->pimpl->dm;
+}
 
-            celix::dm::DependencyManager& getDependencyManager() noexcept override {
-                return this->dm;
-            }
-        protected:
-
-            long registerServiceInternal(celix::ServiceRegistrationEntry&& entry) noexcept  override {
-                long svcId = celix_bundleContext_registerServiceWithOptions(this->c_ctx, &entry.cOpts);
-                if (svcId >= 0) {
-                    std::lock_guard<std::mutex> lock{this->mutex};
-                    this->registrationEntries[svcId] = std::move(entry);
-                }
-                return svcId;
-            }
+inline long celix::BundleContext::Impl::registerServiceInternal(celix::impl::ServiceRegistrationEntry&& entry) noexcept {
+    long svcId = celix_bundleContext_registerServiceWithOptions(this->c_ctx, &entry.cOpts);
+    if (svcId >= 0) {
+        std::lock_guard<std::mutex> lock{this->mutex};
+        this->registrationEntries[svcId] = std::move(entry);
+    }
+    return svcId;
+}
 
-            long trackServicesInternal(celix::ServiceTrackingEntry &&entry) noexcept override {
-                long trkId = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &entry.cOpts);
-                if (trkId >= 0) {
-                    std::lock_guard<std::mutex> lock{this->mutex};
-                    this->trackingEntries[trkId] = std::move(entry);
-                }
-                return trkId;
-            }
+inline long celix::BundleContext::Impl::trackServicesInternal(celix::impl::ServiceTrackingEntry &&entry) noexcept {
+    long trkId = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &entry.cOpts);
+    if (trkId >= 0) {
+        std::lock_guard<std::mutex> lock{this->mutex};
+        this->trackingEntries[trkId] = std::move(entry);
+    }
+    return trkId;
+}
 
-            bool useServiceInternal(
-                    const std::string &serviceName,
-                    const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept override {
-                auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) {
-                    auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle);
-                    celix::Properties props = createFromCProps(c_props);
-                    celix_bundle_t *m_bnd = const_cast<celix_bundle_t*>(c_svcOwner);
-                    celix::impl::BundleImpl bnd{m_bnd};
-                    (*fn)(svc, props, bnd);
-                };
-
-                celix_service_use_options_t opts;
-                std::memset(&opts, 0, sizeof(opts));
-
-                opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
-                opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
-                opts.callbackHandle = (void*)&use;
-                opts.useWithOwner = c_use;
-
-                return celix_bundleContext_useServiceWithOptions(this->c_ctx, &opts);
-            }
+inline bool celix::BundleContext::useServiceInternal(
+        const std::string &serviceName,
+        const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
+    auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) {
+        auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle);
+        celix::Properties props = createFromCProps(c_props);
+        celix_bundle_t *m_bnd = const_cast<celix_bundle_t*>(c_svcOwner);
+        celix::impl::BundleImpl bnd{m_bnd};
+        (*fn)(svc, props, bnd);
+    };
 
-            void useServicesInternal(
-                    const std::string &serviceName,
-                    const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept override {
-                auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) {
-                    auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle);
-                    celix::Properties props = createFromCProps(c_props);
-                    celix_bundle_t *m_bnd = const_cast<celix_bundle_t*>(c_svcOwner);
-                    celix::impl::BundleImpl bnd{m_bnd};
-                    (*fn)(svc, props, bnd);
-                };
-
-                celix_service_use_options_t opts;
-                std::memset(&opts, 0, sizeof(opts));
-
-                opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
-                opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
-                opts.callbackHandle = (void*)&use;
-                opts.useWithOwner = c_use;
-
-                celix_bundleContext_useServicesWithOptions(this->c_ctx, &opts);
-            }
+    celix_service_use_options_t opts;
+    std::memset(&opts, 0, sizeof(opts));
 
-        private:
-            //initialized in ctor
-            bundle_context_t *c_ctx;
-            celix::Framework& fw;
-            celix::impl::BundleImpl bnd;
-            celix::dm::DependencyManager dm;
+    opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
+    opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
+    opts.callbackHandle = (void*)&use;
+    opts.useWithOwner = c_use;
 
-            std::mutex mutex{};
-            std::map<long,ServiceTrackingEntry> trackingEntries{};
-            std::map<long,celix::ServiceRegistrationEntry> registrationEntries{};
-        };
-    }
+    return celix_bundleContext_useServiceWithOptions(this->pimpl->c_ctx, &opts);
+}
+
+inline void celix::BundleContext::useServicesInternal(
+        const std::string &serviceName,
+        const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
+    auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) {
+        auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle);
+        celix::Properties props = createFromCProps(c_props);
+        celix_bundle_t *m_bnd = const_cast<celix_bundle_t*>(c_svcOwner);
+        celix::impl::BundleImpl bnd{m_bnd};
+        (*fn)(svc, props, bnd);
+    };
+
+    celix_service_use_options_t opts;
+    std::memset(&opts, 0, sizeof(opts));
+
+    opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
+    opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
+    opts.callbackHandle = (void*)&use;
+    opts.useWithOwner = c_use;
+
+    celix_bundleContext_useServicesWithOptions(this->pimpl->c_ctx, &opts);
 }
 
 
@@ -330,7 +330,7 @@ long celix::BundleContext::registerServiceWithOptions(const celix::ServiceRegist
         celix_properties_set(c_props, pair.first.c_str(), pair.second.c_str());
     }
 
-    celix::ServiceRegistrationEntry re{};
+    celix::impl::ServiceRegistrationEntry re{};
 
     re.cOpts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
     if (opts.svc != nullptr) {
@@ -362,7 +362,7 @@ long celix::BundleContext::registerServiceWithOptions(const celix::ServiceRegist
     re.cOpts.serviceLanguage = opts.serviceLanguage.c_str();
     re.cOpts.properties = c_props;
 
-    return this->registerServiceInternal(std::move(re));
+    return this->pimpl->registerServiceInternal(std::move(re));
 }
 
 template<typename I>
@@ -383,8 +383,8 @@ long celix::BundleContext::trackServices(const std::string &serviceName,
 
 template<typename I>
 long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTrackingOptions<I>& opts) {
-    celix::ServiceTrackingEntry entry{};
-    entry.functions = std::unique_ptr<ServiceTrackingEntryFunctions>{new ServiceTrackingEntryFunctions()};
+    celix::impl::ServiceTrackingEntry entry{};
+    entry.functions = std::unique_ptr<celix::impl::ServiceTrackingEntryFunctions>{new celix::impl::ServiceTrackingEntryFunctions()};
 
     auto set = opts.set;
     if (set) {
@@ -394,7 +394,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->set = voidfunc;
         entry.cOpts.set = [](void *handle, void *svc) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             (fentry->set)(svc);
         };
     }
@@ -407,7 +407,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->setWithProperties = voidfunc;
         entry.cOpts.setWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             celix::Properties props = createFromCProps(c_props);
             (fentry->setWithProperties)(svc, props);
         };
@@ -421,7 +421,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->setWithOwner = voidfunc;
         entry.cOpts.setWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             celix::Properties props = createFromCProps(c_props);
             auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
             celix::impl::BundleImpl bnd{m_bnd};
@@ -437,7 +437,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->add = voidfunc;
         entry.cOpts.add = [](void *handle, void *svc) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             (fentry->add)(svc);
         };
     }
@@ -450,7 +450,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->addWithProperties = voidfunc;
         entry.cOpts.addWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             celix::Properties props = createFromCProps(c_props);
             (fentry->addWithProperties)(svc, props);
         };
@@ -464,7 +464,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->addWithOwner = voidfunc;
         entry.cOpts.addWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             celix::Properties props = createFromCProps(c_props);
             auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
             celix::impl::BundleImpl bnd{m_bnd};
@@ -480,7 +480,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->remove = voidfunc;
         entry.cOpts.remove = [](void *handle, void *svc) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             (fentry->add)(svc);
         };
     }
@@ -493,7 +493,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->removeWithProperties = voidfunc;
         entry.cOpts.removeWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             celix::Properties props = createFromCProps(c_props);
             (fentry->removeWithProperties)(svc, props);
         };
@@ -507,7 +507,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
         };
         entry.functions->removeWithOwner = voidfunc;
         entry.cOpts.removeWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
-            auto *fentry = static_cast<ServiceTrackingEntryFunctions*>(handle);
+            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
             celix::Properties props = createFromCProps(c_props);
             auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
             celix::impl::BundleImpl bnd{m_bnd};
@@ -522,7 +522,7 @@ long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTracking
 
     entry.cOpts.callbackHandle = entry.functions.get();
 
-    return this->trackServicesInternal(std::move(entry));
+    return this->pimpl->trackServicesInternal(std::move(entry));
 }
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/d8ebc4ab/framework/include/celix/impl/FrameworkImpl.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/impl/FrameworkImpl.h b/framework/include/celix/impl/FrameworkImpl.h
index 175a459..45e5ea5 100644
--- a/framework/include/celix/impl/FrameworkImpl.h
+++ b/framework/include/celix/impl/FrameworkImpl.h
@@ -117,7 +117,7 @@ namespace celix {
 
             bool owner;
             framework_t *c_fwm{nullptr};
-            std::map<long,celix::impl::BundleContextImpl> bundleContextsCache{};
+            std::map<long,celix::BundleContext> bundleContextsCache{};
             std::vector<celix::impl::BundleImpl> fwBundle{}; //optional entry
 
         };

http://git-wip-us.apache.org/repos/asf/celix/blob/d8ebc4ab/framework/include/celix_bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_bundle_context.h b/framework/include/celix_bundle_context.h
index 4c7af12..4afbe5b 100644
--- a/framework/include/celix_bundle_context.h
+++ b/framework/include/celix_bundle_context.h
@@ -127,6 +127,7 @@ typedef struct celix_service_registration_options {
  * Macro to create a empty celix_service_registration_options_t type.
  */
 #define CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS { .svc = NULL, \
+    .factory = NULL, \
     .serviceName = NULL, \
     .properties = NULL, \
     .serviceLanguage = NULL, \