You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Andrus Adamchik <an...@objectstyle.org> on 2009/11/15 22:57:54 UTC
Re: IOC container
Just for kicks wrote a simple DI container for Cayenne. I checked it
in partially to sanbdox folder until the ASF SVN repo went down (http://monitoring.apache.org/
), so I'll commit the rest on Monday, or whenever SVN becomes available.
This no-frills DI container took me only a couple of hours to write
(it borrows some Guice API, but implementation is all mine). It supports
* annotation-based field dependency injection
* binding interfaces to implementation classes via fluent API
* binding interfaces to "provider" (same as "factory") classes
* merging multiple DI "modules".
The whole thing is only 14K after compilation (so it beats all full
featured DI containers in size). Of course that's because it doesn't
have all the fancy stuff (of which we'll add at least a few more
things) such as constructor injection, dependency cycle resolving,
dynamic interface proxies, bound object lifecycle, integration with
Spring, etc. Since we are not planning a general purpose container, we
might survive without most of those.
Here is how the current Configuration class might look like when it is
based on DI:
public class Configuration {
private Injector injector;
public Configuration() {
this(new CayenneModule());
}
public Configuration(Module... modules) {
this.injector = DIBootstrap.createInjector(modules);
}
public DataChannel getDataChannel() {
return injector.getInstance(DataChannel.class);
}
public ObjectContext getNewContext() {
return injector.getInstance(ObjectContext.class);
}
// we may create getters for other "services" if we need to
}
And the actual configuration class (aka "module") used above:
public class CayenneModule implements Module {
public void configure(Binder binder) {
binder.bind(EventManager.class).to(EventManagerImpl.class);
binder.bind(DataChannel.class).to(DataDomain.class);
binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
// an so on...
}
}
"CayenneModule" is what users can override (e.g. simply subclass),
providing alternative implementations for some services.
The next step in this prototype would be an attempt to define the
current Cayenne stack in terms of DI.
Andrus
On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <andrus@objectstyle.org
> > wrote:
>
>> And I just discovered that both Spring (3.0RC1) and Juice (trunk)
>> support
>> the annotations from this JSR. So it could make sense for us to use
>> these
>> annotations internally as well. Couldn't dig any info on the
>> Tapestry IoC
>> support for this JSR, but they are on the JSR "support group", so
>> at least
>> they are watching it.
>
> Thiago, the Tapestry member on the support group, just learned that it
> had been approved. Howard didn't even know the JSR existed. There's
> no discussion on adding in the annotation support to Tapestry IoC and
> I suspect it will happen, but Tapestry is behind the ball on that one.
>
> --
> Kevin
>
Re: IOC container
Posted by Michael Gentry <mg...@masslight.net>.
I think getting rid of DataDomains (at least in the Modeler) ties into
my #1 here:
http://markmail.org/message/wf7y73rgorj4bi4h
mrg
On Mon, Nov 16, 2009 at 9:43 AM, Andrus Adamchik <an...@objectstyle.org> wrote:
> And finally, unrelated, but since DataDomains were mentioned... I've been
> thinking to do away with multiple DataDomains. They are really independent
> stacks, so why bother keeping them together in one project. The users can
> start multiple Cayenne stacks instead.
Re: IOC container
Posted by Andrus Adamchik <an...@objectstyle.org>.
Yeah, it's been briefly mentioned in this thread: http://markmail.org/message/xyyixpaolg45cj4x
The spec jar is just 4K. The annotations that I used are compatible
with it, so if during development we decide it makes sense to stay
standard-compliant in this case, it won't be a problem to switch.
(BTW, SVN is back up and I checked in the remaining provider code).
Andrus
On Nov 16, 2009, at 8:54 AM, Andrey Razumovsky wrote:
> Hi,
>
> I'm not sure it will be helpful, but there's JSR-330 spec for that
> (instead
> of borrowing straightly from Guice):
> http://jcp.org/aboutJava/communityprocess/final/jsr330/index.html
>
> It defines several useful classes and annotations, as @Inject and
> Provider<T>
>
> 2009/11/16 Andrus Adamchik <an...@objectstyle.org>
>
>> Just for kicks wrote a simple DI container for Cayenne. I checked
>> it in
>> partially to sanbdox folder until the ASF SVN repo went down (
>> http://monitoring.apache.org/), so I'll commit the rest on Monday, or
>> whenever SVN becomes available.
>>
>> This no-frills DI container took me only a couple of hours to write
>> (it
>> borrows some Guice API, but implementation is all mine). It supports
>>
>> * annotation-based field dependency injection
>> * binding interfaces to implementation classes via fluent API
>> * binding interfaces to "provider" (same as "factory") classes
>> * merging multiple DI "modules".
>>
>> The whole thing is only 14K after compilation (so it beats all full
>> featured DI containers in size). Of course that's because it
>> doesn't have
>> all the fancy stuff (of which we'll add at least a few more things)
>> such as
>> constructor injection, dependency cycle resolving, dynamic interface
>> proxies, bound object lifecycle, integration with Spring, etc.
>> Since we are
>> not planning a general purpose container, we might survive without
>> most of
>> those.
>>
>> Here is how the current Configuration class might look like when it
>> is
>> based on DI:
>>
>> public class Configuration {
>>
>> private Injector injector;
>>
>> public Configuration() {
>> this(new CayenneModule());
>> }
>>
>> public Configuration(Module... modules) {
>> this.injector = DIBootstrap.createInjector(modules);
>> }
>>
>> public DataChannel getDataChannel() {
>> return injector.getInstance(DataChannel.class);
>> }
>>
>> public ObjectContext getNewContext() {
>> return injector.getInstance(ObjectContext.class);
>> }
>>
>> // we may create getters for other "services" if we need to
>> }
>>
>> And the actual configuration class (aka "module") used above:
>>
>> public class CayenneModule implements Module {
>>
>> public void configure(Binder binder) {
>>
>> binder.bind(EventManager.class).to(EventManagerImpl.class);
>> binder.bind(DataChannel.class).to(DataDomain.class);
>>
>> binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
>>
>> binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
>> // an so on...
>> }
>> }
>>
>> "CayenneModule" is what users can override (e.g. simply subclass),
>> providing alternative implementations for some services.
>>
>> The next step in this prototype would be an attempt to define the
>> current
>> Cayenne stack in terms of DI.
>>
>> Andrus
>>
>>
>> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>>
>> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <andrus@objectstyle.org
>> >
>>> wrote:
>>>
>>> And I just discovered that both Spring (3.0RC1) and Juice (trunk)
>>> support
>>>> the annotations from this JSR. So it could make sense for us to
>>>> use these
>>>> annotations internally as well. Couldn't dig any info on the
>>>> Tapestry IoC
>>>> support for this JSR, but they are on the JSR "support group", so
>>>> at
>>>> least
>>>> they are watching it.
>>>>
>>>
>>> Thiago, the Tapestry member on the support group, just learned
>>> that it
>>> had been approved. Howard didn't even know the JSR existed.
>>> There's
>>> no discussion on adding in the annotation support to Tapestry IoC
>>> and
>>> I suspect it will happen, but Tapestry is behind the ball on that
>>> one.
>>>
>>> --
>>> Kevin
>>>
>>>
>>
>
>
> --
> Andrey
Re: IOC container
Posted by Andrey Razumovsky <ra...@gmail.com>.
Hi,
I'm not sure it will be helpful, but there's JSR-330 spec for that (instead
of borrowing straightly from Guice):
http://jcp.org/aboutJava/communityprocess/final/jsr330/index.html
It defines several useful classes and annotations, as @Inject and
Provider<T>
2009/11/16 Andrus Adamchik <an...@objectstyle.org>
> Just for kicks wrote a simple DI container for Cayenne. I checked it in
> partially to sanbdox folder until the ASF SVN repo went down (
> http://monitoring.apache.org/), so I'll commit the rest on Monday, or
> whenever SVN becomes available.
>
> This no-frills DI container took me only a couple of hours to write (it
> borrows some Guice API, but implementation is all mine). It supports
>
> * annotation-based field dependency injection
> * binding interfaces to implementation classes via fluent API
> * binding interfaces to "provider" (same as "factory") classes
> * merging multiple DI "modules".
>
> The whole thing is only 14K after compilation (so it beats all full
> featured DI containers in size). Of course that's because it doesn't have
> all the fancy stuff (of which we'll add at least a few more things) such as
> constructor injection, dependency cycle resolving, dynamic interface
> proxies, bound object lifecycle, integration with Spring, etc. Since we are
> not planning a general purpose container, we might survive without most of
> those.
>
> Here is how the current Configuration class might look like when it is
> based on DI:
>
> public class Configuration {
>
> private Injector injector;
>
> public Configuration() {
> this(new CayenneModule());
> }
>
> public Configuration(Module... modules) {
> this.injector = DIBootstrap.createInjector(modules);
> }
>
> public DataChannel getDataChannel() {
> return injector.getInstance(DataChannel.class);
> }
>
> public ObjectContext getNewContext() {
> return injector.getInstance(ObjectContext.class);
> }
>
> // we may create getters for other "services" if we need to
> }
>
> And the actual configuration class (aka "module") used above:
>
> public class CayenneModule implements Module {
>
> public void configure(Binder binder) {
> binder.bind(EventManager.class).to(EventManagerImpl.class);
> binder.bind(DataChannel.class).to(DataDomain.class);
>
> binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
>
> binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
> // an so on...
> }
> }
>
> "CayenneModule" is what users can override (e.g. simply subclass),
> providing alternative implementations for some services.
>
> The next step in this prototype would be an attempt to define the current
> Cayenne stack in terms of DI.
>
> Andrus
>
>
> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>
> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <an...@objectstyle.org>
>> wrote:
>>
>> And I just discovered that both Spring (3.0RC1) and Juice (trunk) support
>>> the annotations from this JSR. So it could make sense for us to use these
>>> annotations internally as well. Couldn't dig any info on the Tapestry IoC
>>> support for this JSR, but they are on the JSR "support group", so at
>>> least
>>> they are watching it.
>>>
>>
>> Thiago, the Tapestry member on the support group, just learned that it
>> had been approved. Howard didn't even know the JSR existed. There's
>> no discussion on adding in the annotation support to Tapestry IoC and
>> I suspect it will happen, but Tapestry is behind the ball on that one.
>>
>> --
>> Kevin
>>
>>
>
--
Andrey
Re: IOC container
Posted by Andrus Adamchik <an...@objectstyle.org>.
On Nov 16, 2009, at 4:43 PM, Andrus Adamchik wrote:
> I don't have all the details yet, but the container API will be
> extended as needed to fit our needs. For now I am thinking that all
> cases where we need to access objects by name, will be delegated to
> Configuration and other objects outside container. The container may
> store maps of all names, and Configuration will be a frontend to
> read from those maps.
I should also mention that I am not fully clear yet about a separation
between the "container services" and "model objects" defined in the
XML project. Certain things (such as JGroups configuration) do not
belong in the project and should be re-classified as container
services. DataDomain / DataNodes are somewhat in the middle. Their
structure is defined by the user, but Cayenne injects all services
they need to operate.
Will need to play with it a bit more, but the direction is to keep the
environment agnostic model (DataMap) separate from environment-
specific stuff (access stack). Modeling access stack in the modeler is
a nice shortcut to get people started, but doesn't address JEE
environment complexity well.
Andrus
Re: IOC container
Posted by Andrus Adamchik <an...@objectstyle.org>.
Do you mean multiple DataDomains?
I don't have all the details yet, but the container API will be
extended as needed to fit our needs. For now I am thinking that all
cases where we need to access objects by name, will be delegated to
Configuration and other objects outside container. The container may
store maps of all names, and Configuration will be a frontend to read
from those maps.
But if we find that extending the container is beneficial, we can do
that too. E.g. I am planning something similar to Tapestry
configurations for the users to register/override ExtendedTypes, so
that the users don't have to redefine all types if they need to add
just one extra object.
Also to ensure we are on the same page, I am not planning app-facing
injection, just internal injection of Cayenne classes between
themselves. I.e. we won't inject anything in an app class that is
calling an ObjectContext (unless it is an override for the standard
service).
And finally, unrelated, but since DataDomains were mentioned... I've
been thinking to do away with multiple DataDomains. They are really
independent stacks, so why bother keeping them together in one
project. The users can start multiple Cayenne stacks instead.
Andrus
On Nov 16, 2009, at 4:28 PM, Michael Gentry wrote:
> How are you envisioning injecting an ObjectContext for different
> DataNodes, etc?
>
> Thanks,
>
> mrg
>
>
> On Sun, Nov 15, 2009 at 4:57 PM, Andrus Adamchik <andrus@objectstyle.org
> > wrote:
>> Just for kicks wrote a simple DI container for Cayenne. I checked
>> it in
>> partially to sanbdox folder until the ASF SVN repo went down
>> (http://monitoring.apache.org/), so I'll commit the rest on Monday,
>> or
>> whenever SVN becomes available.
>>
>> This no-frills DI container took me only a couple of hours to write
>> (it
>> borrows some Guice API, but implementation is all mine). It supports
>>
>> * annotation-based field dependency injection
>> * binding interfaces to implementation classes via fluent API
>> * binding interfaces to "provider" (same as "factory") classes
>> * merging multiple DI "modules".
>>
>> The whole thing is only 14K after compilation (so it beats all full
>> featured
>> DI containers in size). Of course that's because it doesn't have
>> all the
>> fancy stuff (of which we'll add at least a few more things) such as
>> constructor injection, dependency cycle resolving, dynamic interface
>> proxies, bound object lifecycle, integration with Spring, etc.
>> Since we are
>> not planning a general purpose container, we might survive without
>> most of
>> those.
>>
>> Here is how the current Configuration class might look like when it
>> is based
>> on DI:
>>
>> public class Configuration {
>>
>> private Injector injector;
>>
>> public Configuration() {
>> this(new CayenneModule());
>> }
>>
>> public Configuration(Module... modules) {
>> this.injector = DIBootstrap.createInjector(modules);
>> }
>>
>> public DataChannel getDataChannel() {
>> return injector.getInstance(DataChannel.class);
>> }
>>
>> public ObjectContext getNewContext() {
>> return injector.getInstance(ObjectContext.class);
>> }
>>
>> // we may create getters for other "services" if we need to
>> }
>>
>> And the actual configuration class (aka "module") used above:
>>
>> public class CayenneModule implements Module {
>>
>> public void configure(Binder binder) {
>>
>> binder.bind(EventManager.class).to(EventManagerImpl.class);
>> binder.bind(DataChannel.class).to(DataDomain.class);
>>
>> binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
>>
>> binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
>> // an so on...
>> }
>> }
>>
>> "CayenneModule" is what users can override (e.g. simply subclass),
>> providing
>> alternative implementations for some services.
>>
>> The next step in this prototype would be an attempt to define the
>> current
>> Cayenne stack in terms of DI.
>>
>> Andrus
>>
>> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>>
>>> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <andrus@objectstyle.org
>>> >
>>> wrote:
>>>
>>>> And I just discovered that both Spring (3.0RC1) and Juice (trunk)
>>>> support
>>>> the annotations from this JSR. So it could make sense for us to
>>>> use these
>>>> annotations internally as well. Couldn't dig any info on the
>>>> Tapestry IoC
>>>> support for this JSR, but they are on the JSR "support group", so
>>>> at
>>>> least
>>>> they are watching it.
>>>
>>> Thiago, the Tapestry member on the support group, just learned
>>> that it
>>> had been approved. Howard didn't even know the JSR existed.
>>> There's
>>> no discussion on adding in the annotation support to Tapestry IoC
>>> and
>>> I suspect it will happen, but Tapestry is behind the ball on that
>>> one.
>>>
>>> --
>>> Kevin
>>>
>>
>>
>
Re: IOC container
Posted by Michael Gentry <mg...@masslight.net>.
How are you envisioning injecting an ObjectContext for different DataNodes, etc?
Thanks,
mrg
On Sun, Nov 15, 2009 at 4:57 PM, Andrus Adamchik <an...@objectstyle.org> wrote:
> Just for kicks wrote a simple DI container for Cayenne. I checked it in
> partially to sanbdox folder until the ASF SVN repo went down
> (http://monitoring.apache.org/), so I'll commit the rest on Monday, or
> whenever SVN becomes available.
>
> This no-frills DI container took me only a couple of hours to write (it
> borrows some Guice API, but implementation is all mine). It supports
>
> * annotation-based field dependency injection
> * binding interfaces to implementation classes via fluent API
> * binding interfaces to "provider" (same as "factory") classes
> * merging multiple DI "modules".
>
> The whole thing is only 14K after compilation (so it beats all full featured
> DI containers in size). Of course that's because it doesn't have all the
> fancy stuff (of which we'll add at least a few more things) such as
> constructor injection, dependency cycle resolving, dynamic interface
> proxies, bound object lifecycle, integration with Spring, etc. Since we are
> not planning a general purpose container, we might survive without most of
> those.
>
> Here is how the current Configuration class might look like when it is based
> on DI:
>
> public class Configuration {
>
> private Injector injector;
>
> public Configuration() {
> this(new CayenneModule());
> }
>
> public Configuration(Module... modules) {
> this.injector = DIBootstrap.createInjector(modules);
> }
>
> public DataChannel getDataChannel() {
> return injector.getInstance(DataChannel.class);
> }
>
> public ObjectContext getNewContext() {
> return injector.getInstance(ObjectContext.class);
> }
>
> // we may create getters for other "services" if we need to
> }
>
> And the actual configuration class (aka "module") used above:
>
> public class CayenneModule implements Module {
>
> public void configure(Binder binder) {
> binder.bind(EventManager.class).to(EventManagerImpl.class);
> binder.bind(DataChannel.class).to(DataDomain.class);
>
> binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
> binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
> // an so on...
> }
> }
>
> "CayenneModule" is what users can override (e.g. simply subclass), providing
> alternative implementations for some services.
>
> The next step in this prototype would be an attempt to define the current
> Cayenne stack in terms of DI.
>
> Andrus
>
> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>
>> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <an...@objectstyle.org>
>> wrote:
>>
>>> And I just discovered that both Spring (3.0RC1) and Juice (trunk) support
>>> the annotations from this JSR. So it could make sense for us to use these
>>> annotations internally as well. Couldn't dig any info on the Tapestry IoC
>>> support for this JSR, but they are on the JSR "support group", so at
>>> least
>>> they are watching it.
>>
>> Thiago, the Tapestry member on the support group, just learned that it
>> had been approved. Howard didn't even know the JSR existed. There's
>> no discussion on adding in the annotation support to Tapestry IoC and
>> I suspect it will happen, but Tapestry is behind the ball on that one.
>>
>> --
>> Kevin
>>
>
>
Re: IOC container
Posted by Andrus Adamchik <an...@objectstyle.org>.
On Nov 21, 2009, at 11:49 PM, Andrus Adamchik wrote:
>
> * annotation-based field dependency injection
> * annotation-based constructor dependency injection
> * injection of map and list "configurations" (allows to add things
> like extra ExtendedTypes)
> * binding interfaces to implementation classes via fluent API
> * binding interfaces to "provider" (same as "factory") classes
> * merging multiple DI "modules"
> * dependency cycle detection
[one more]
* standard and user-defined scopes for bound objects.
Andrus
Re: IOC container
Posted by Andrus Adamchik <an...@objectstyle.org>.
Just finished all the main features I'd like to see in the DI
container. So here is a new checklist:
* annotation-based field dependency injection
* annotation-based constructor dependency injection
* injection of map and list "configurations" (allows to add things
like extra ExtendedTypes)
* binding interfaces to implementation classes via fluent API
* binding interfaces to "provider" (same as "factory") classes
* merging multiple DI "modules"
* dependency cycle detection
The container is still pretty small (all the di package classes are
~26K when compiled), and it seems like it was worth the effort (vs.
just using Guice for instance).
Now will try to find time to define a Cayenne stack based on the DI,
instead of the old Configuration:
https://svn.apache.org/repos/asf/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/
Andrus
On Nov 15, 2009, at 11:57 PM, Andrus Adamchik wrote:
> Just for kicks wrote a simple DI container for Cayenne. I checked it
> in partially to sanbdox folder until the ASF SVN repo went down (http://monitoring.apache.org/
> ), so I'll commit the rest on Monday, or whenever SVN becomes
> available.
>
> This no-frills DI container took me only a couple of hours to write
> (it borrows some Guice API, but implementation is all mine). It
> supports
>
> * annotation-based field dependency injection
> * binding interfaces to implementation classes via fluent API
> * binding interfaces to "provider" (same as "factory") classes
> * merging multiple DI "modules".
>
> The whole thing is only 14K after compilation (so it beats all full
> featured DI containers in size). Of course that's because it doesn't
> have all the fancy stuff (of which we'll add at least a few more
> things) such as constructor injection, dependency cycle resolving,
> dynamic interface proxies, bound object lifecycle, integration with
> Spring, etc. Since we are not planning a general purpose container,
> we might survive without most of those.
>
> Here is how the current Configuration class might look like when it
> is based on DI:
>
> public class Configuration {
>
> private Injector injector;
>
> public Configuration() {
> this(new CayenneModule());
> }
>
> public Configuration(Module... modules) {
> this.injector = DIBootstrap.createInjector(modules);
> }
>
> public DataChannel getDataChannel() {
> return injector.getInstance(DataChannel.class);
> }
>
> public ObjectContext getNewContext() {
> return injector.getInstance(ObjectContext.class);
> }
>
> // we may create getters for other "services" if we need to
> }
>
> And the actual configuration class (aka "module") used above:
>
> public class CayenneModule implements Module {
>
> public void configure(Binder binder) {
> binder.bind(EventManager.class).to(EventManagerImpl.class);
> binder.bind(DataChannel.class).to(DataDomain.class);
> binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
> binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
> // an so on...
> }
> }
>
> "CayenneModule" is what users can override (e.g. simply subclass),
> providing alternative implementations for some services.
>
> The next step in this prototype would be an attempt to define the
> current Cayenne stack in terms of DI.
>
> Andrus
>
> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>
>> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <andrus@objectstyle.org
>> > wrote:
>>
>>> And I just discovered that both Spring (3.0RC1) and Juice (trunk)
>>> support
>>> the annotations from this JSR. So it could make sense for us to
>>> use these
>>> annotations internally as well. Couldn't dig any info on the
>>> Tapestry IoC
>>> support for this JSR, but they are on the JSR "support group", so
>>> at least
>>> they are watching it.
>>
>> Thiago, the Tapestry member on the support group, just learned that
>> it
>> had been approved. Howard didn't even know the JSR existed. There's
>> no discussion on adding in the annotation support to Tapestry IoC and
>> I suspect it will happen, but Tapestry is behind the ball on that
>> one.
>>
>> --
>> Kevin
>>
>
>