[ https://issues.apache.org/jira/browse/FELIX-5320?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15422636#comment-15422636 ]
Pierre De Rop commented on FELIX-5320: -------------------------------------- Hello Andrea; You normally use an Adapter in order to create another component on top of an existing one. Typically, for example you want to create a management component (like a servlet, or an amdatu restful web service) on top of an existing service component. say you are developing a nosql database, and you have for instance a "MyNoSqlDatabase" service component: {code} dm.add(createComponent() .setImplementation(MyNoSqlDatabaseImpl.class) .setInterface(MyNoSqlDatabase.class.getName(), null)); {code} Now, assume you wan to make a restful web service which allows to administer your database. To do so, you wan to be modular and you want to make (for example) a jax rs web component, which would allow for example to display the number of transactions performed, or tune your nosql database from the web. So, you would in this case write an adapter component, like the following, which creates an amdatu web service component on top of the existing MyNoSqlDatabase service component: {code} dm.add(createAdapterService(MyNoSqlDatabase.class, null) .setImplementation(MyNoSqlDatabaseAdmin.class) .setInterface(Object.class.getName(), null)); {code} and your jax rs amdatu web service used to aminister your no sql database: {code} @Path("mynosql") class MyNoSqlDatabaseAdmin { volatile MyNoSqlDatabase database; // original database component, injected @GET @Produces("text/plain") public int transactions() { return database.getTransactions(); } } {code} I don't know if you need or not adapter, but let's assume that yes, you need an adapter. So, getting back to your initial question: your want to add a dynamic dependency for your adapter, based on the adaptee. So, in our example, the adaptee is "MyNoSqlDatabase". Now, assume that the MyNoSqlDatabase has some services properties. These service properties are by default propagated to the adaptee service properties (MyNoSqlDatabaseAdmin). Now, if you want to get access to the adaptee service properties, you can simply define a callback for the adaptee, instead of inject it in a compatible map field. And the callback may then use a signature which takes the adaptee, as well as a map for the adaptee service properties. You can then just keep the adaptee service properties and use it from your adapter init method in order to decide to add (or not) an additiona adapter dependency. let's see this a a concrete example. First, let's redefine the adapter Activator: {code} dm.add(createAdapterService(MyNoSqlDatabase.class, null, "setDatabase", null /* no change callback */, null /* no remove callback */) .setImplementation(MyNoSqlDatabaseAdmin.class) .setInterface(Object.class.getName(), null)); {code} and let's refactor the adapter with the "setDatabase" callback {code} @Path("mynosql") class MyNoSqlDatabaseAdmin { volatile MyNoSqlDatabase database; // original database component volatile Map databaseProperties; // original database service properties volatile SomeOtherService otherService; // dependency dynamically added from init method void setDatabase(MyNoSqlDatabase, Map properties) { this.database = database; this.databaseProperties = properties; } void init(Component comp) { // at this point, the database and database properties have been injected: then depending on the database service properties (which are by default // propagated to our adapter service properties), then possibly add one more service dependency: if (databasePropertiesRequiresAnotherDependency(this.databaseProperties)) { DependencyManager dm = c.getDependencyManager(); String filter = getFilter(databaseProperties); comp.add(dm.createServiceDependency().setService(SomeOtherService.class, filter).setRequired(true)); } } @GET @Produces("text/plain") public int transactions() { return database.getTransactions(); } } {code} so, in the above example, the database (adaptee) is injected using the setDatabase method and the service properties are kept in the "databaseProperties", which is then reused in the init method, in order to possibly add an extra dependency. Notice that if you don't need an adapter at all, you can do the same with a regular Component. does this help ? > Dependency Manager: adapter service propagates adaptee properties *after* the > init (and start) callbacks are called > ------------------------------------------------------------------------------------------------------------------- > > Key: FELIX-5320 > URL: https://issues.apache.org/jira/browse/FELIX-5320 > Project: Felix > Issue Type: Bug > Components: Dependency Manager > Affects Versions: org.apache.felix.dependencymanager-r8 > Reporter: Andrea Leofreddi > > In an adapter service, created using the createAdapterService method of > DependencyManager class, one would expect to find the adaptee's properties > being propagated to the adapter service itself, as stated in the > documentation > (http://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/reference/component-adapter.html). > Instead no propagation happens, and both init and start methods won't see any > propagated properties. > After investigating I've found that propagations indeed happens (via > AdapterServiceImpl's propagateAdapteeProperties) only after the callbacks are > called. -- This message was sent by Atlassian JIRA (v6.3.4#6332)