it's a slow weekend. Everyone that is anyone has headed off to the states. Apart from me :(
So, I thought I'd stir the OO nest.
Do you inject , or use factories for your OO stuff ?
I have been using factories, but am getting attracted to dependency Injection. However, I keep getting torn between the two.
Kinda like girlfriend 1.0 and girlfriend 2.0 .. ;)
what's your poison - and why ?
bugger. I saw the forum " OpenEdge Architecture" and thought that this was the most appropriate for the question. However, it turns out that "OpenEdge Architecture" actually means "OE Architecture Cloud and Arcade".
:(
perhaps the title of the forum could be changed somewhat ...
Jean, could you move this please ? thanks !
Well, I'm still in the old world as well. And it's weekend here ;-)
Anyway, concerning your question. I use both, Factory controlling lifespan and default implementation of interfaces, and inject what object comes out of the factory into whatever needs it.
no chance. I would rather use include files ;)
safe flight my friend.
On 4 October 2014 18:07, Mike Fechner
wrote:
> AW: do you inject ?
> Reply by Mike Fechner
> Somewhere between the old world and the new world right now – but agree with
> Bronco.
>
> So Julian, you’ll have to get along with two girlfirneds there.
>
>
>
> Stop receiving emails on this subject.
>
> Flag this post as spam/abuse.
--
Julian Lyndon-Smith
IT Director,
dot.r
http://www.dotr.com
old world is still the good world ;)
so, take this scenario
Class A needs Class B needs Class C
they all need a logger instance.
so A gets the logger instance from the "main" framework. A passes it
to B, which passes it to C.
all well and good.
*but*
now C needs a stomp connector instance
so, does C interrogate the factory (as A and B don't need it)
or should it be passed down the chain from A to B to C (even though A
and B don;t need it)
do things get more complicated if C can be instantiated from D ?
form a DI point of view, C needs to be passed the stomp connector. It
seems kinda wrong for C to call the factory.
But then it seems wrong that B (and therefore A) must have a stomp
instance that they never use
On 4 October 2014 18:01, Bronco wrote:
> RE: do you inject ?
> Reply by Bronco
>
> Well, I'm still in the old world as well. And it's weekend here ;-)
>
> Anyway, concerning your question. I use both, Factory controlling lifespan
> and default implementation of interfaces, and inject what object comes out
> of the factory into whatever needs it.
>
> Stop receiving emails on this subject.
>
> Flag this post as spam/abuse.
--
Julian Lyndon-Smith
IT Director,
dot.r
http://www.dotr.com
That why the STOMP should have a decent interface. So you can do a def var stompAdapter as IStompAdapter no-undo, in class B, call the Factory for an instance of IStompAdapter and pass that to C. This is a textbook case for interfaces.
yeah, interfaces are the key - but it was just that B would have to
call the factory that I was uncomfortable with.
On 4 October 2014 18:08, Julian Lyndon-Smith wrote:
> old world is still the good world ;)
>
> so, take this scenario
>
> Class A needs Class B needs Class C
>
> they all need a logger instance.
>
> so A gets the logger instance from the "main" framework. A passes it
> to B, which passes it to C.
>
> all well and good.
>
> *but*
>
> now C needs a stomp connector instance
>
> so, does C interrogate the factory (as A and B don't need it)
>
> or should it be passed down the chain from A to B to C (even though A
> and B don;t need it)
>
> do things get more complicated if C can be instantiated from D ?
>
> form a DI point of view, C needs to be passed the stomp connector. It
> seems kinda wrong for C to call the factory.
>
> But then it seems wrong that B (and therefore A) must have a stomp
> instance that they never use
>
>
>
> On 4 October 2014 18:01, Bronco wrote:
>> RE: do you inject ?
>> Reply by Bronco
>>
>> Well, I'm still in the old world as well. And it's weekend here ;-)
>>
>> Anyway, concerning your question. I use both, Factory controlling lifespan
>> and default implementation of interfaces, and inject what object comes out
>> of the factory into whatever needs it.
>>
>> Stop receiving emails on this subject.
>>
>> Flag this post as spam/abuse.
>
>
>
> --
> Julian Lyndon-Smith
> IT Director,
> dot.r
> http://www.dotr.com
--
Julian Lyndon-Smith
IT Director,
dot.r
http://www.dotr.com
Let's not get into a discussion what a Factory is or is not. (in Spring 2.0 XmlBeanFactory inherited from DefaultSingletonBeanRegistry)
Let's not get into a discussion what a Factory is or is not. (in Spring 2.0 XmlBeanFactory inherited from DefaultSingletonBeanRegistry)
Flag this post as spam/abuse.
btw Mike, are you on Iceland?
No, already passed that. A bit East of Boston as I see it. Real “cloud-computing”…
haha, I should have known.
so, lemme get this straight. Class B has a dependency on an "logger" class.
#1 so, normal OO code is
/** class B */ def var myLogger as Logger no-undo. myLogger = new Logger().
[snip]
delete object myLogger. /** or wait for GC */
we both agree that this is bad. Tight coupling, difficult to test, etc
#2 service locater code is
/** class B */ def var _myLogger as ILogger no-undo. /** define as an interface */ _myLogger = LoggerFactory:instance() [snip] delete object myLogger. /** or wait for GC */
#3 DI code is
/** class B */ def var _myLogger as Ilogger no-undo. constructor B(p_logger as ILogger): _myLogger = p_logger. end constructor. [snip]
Now, I know that #2 is widely considered to be an anti-pattern (bad boy! don't do this) for a couple of reasons, the primary being that you cannot determine the dependencies of the class
*however* , now we need another class to instantiate B , in order to pass in the appropriate parameters to the constructor . Where does class A get the instances to pass to the new instance of class B ? From a service locator / factory ?
Also - who now determines the lifetime of the instances create by A to in order to pass to B ? Is it still B ? If so, then we now have to explicitly delete the instances in the destructor of class B or we my get memory leaks
I really want to use #3. It just seems (perhaps it's because we don't have a proper DI framework in openedge) that we are moving the usage of service locators to another level. But we're still using them.
something worth reading in this respect:
www.devtrends.co.uk/.../how-not-to-do-dependency-injection-the-static-or-singleton-container
thanks for the link - what i still don't "get" is this ... if my class contains this code
using Progress.Lang.*. block-level on error undo, throw. class HomeController: def var _service as IExampleService no-undo. constructor HomeController(serviceFactory as IServiceFactory): _service = serviceFactory; end constructor. method public void Index(): _service:GetSomething(). end method. end class.
then at some point the object calling HomeController needs to know the instance of serviceFactory
I guess that the line is where a concrete application calls generic functionality. For example, you have a CachingManager class, and this CachingManager is programmed against the ICaching interface. The implementation of ICaching is injected. So this could be a DbCaching class or a MemoryCaching class or whatever caching you can come up with.The concrete implementation of ICaching is injected into the CachingManager by the application which uses the CachingManager (iow: who has the need for caching). This is sound because the application (read: the programmer) should know on the application level which type of cache works best at the particular situation. As far as instantiation goes, the application could bluntly istantiate a cache type (class) and inject it or instantiate it via a factory which get its information from a configuration file (in which case the used caching strategy is externalized). I hope this makes sense.
edit: typo
as far as the last two bullets:
- DI isn't necessarily done via constructors, methods are perfectly suitable to accomplish the same goal.
- well, depends. What I see is that the OO knowledge of users most of the time doesn't go beyond inheritance, so no need there. On the other hand, yes of course we miss a proper DI framework. Personally I'm a fan of Spring. More so, I made an OpenEdge implementation of Spring (<OE11 however). Maybe I should update the sources and post it on github.
edit: typo (again)
one more, found my 4/5 year old Spring implementation:
https://github.com/bfv/oestuff
It's based on Spring 2.0/2.5, this is important because it implies an XSD for the bean factory XML. There's undoubtedly some classic errors in there, I haven't touched this code in quite a while, other than for some minor stuff.
> we don't have a proper DI framework in openedge
Isn't this a proper one: github.com/.../InjectABL
> are we missing a proper DI framework in progress
I'm using Peter Judge's injectABL for some years now in a framework that is in production for a couple of years, it works and looks proper to me. Have you had a look at injectABL?
I did a while back - but before I got DI ;)
I'll have another look. However, we don't use appserver (hopefully
this won't matter) and the link to docs
(http://communities.progress.com/pcom/docs/DOC-105068) is invalid
Julian
On 8 October 2014 08:04, agent_008_nl
wrote:
> RE: do you inject ?
> Reply by agent_008_nl
>
>> are we missing a proper DI framework in progress
>
> I'm using Peter Judge's injectABL for some years now in a framework that is
> in production for a couple of years, it works and looks proper to me. Have
> you had a look at injectABL?
>
> Stop receiving emails on this subject.
>
> Flag this post as spam/abuse.
--
Julian Lyndon-Smith
IT Director,
dot.r
http://www.dotr.com
I'm almost sure I posted this link before, but for those who have not seen it here it is again: tutorials.jenkov.com/.../dependency-injection-replacing-factory-patterns.html
Of course that should not matter. Is this the doc you're looking for ?:
community.progress.com/.../998.oeri-dependency-injection-container-injectabl.aspx
I had some trouble learning to work with injectABL but Peter Judge was very helpful. And there is some samplecode in autoedge|the factory (maybe on the clientside also, I don't know because my openedge framework is on the backend only).
Could be a nice session on pugchallenges: Peter Judge on these matters, with an injectABL demo.
Yes yes, nothing wrong with a bit of merchandising, I know you by now "Beer here! German sausages! The best in the world!", but what I'm saying is that the subject is worth a complete, dedicated, session.
I would not be surprised to hear that I'm the only user in the world of injectABL, it deserves more.
Yes yes, nothing wrong with a bit of merchandising, I know you by now "Beer here! German sausages! The best in the world!", but what I'm saying is that the subject is worth a complete, dedicated, session.
I would not be surprised to hear that I'm the only user in the world of injectABL, it deserves more.
Flag this post as spam/abuse.
I wouldn't dare. No, I'm saying that I expect you to clothe in traditional German costume (Trachten in German, see f.e. http://www.gastroland.info/ and have fun) in Köln, sell those beerglasses that contain a whole liter and Bockwurst. And pleas bring a bladder chapel from Bayern (fe the Trifterner Blosn in the link above, they will come in Trachten also), time for Oktoberfest and lots of beer.
Oktoberfest in November is no problem for the Trifterner Blosn I suppose.
Funny, I sent the same link to the peg on june 23. Worth reading too btw, "on those handy singletons (one running instance per session) that you instantiate via a static, making it possible to use the class without first having to new (for example knowledgebase.progress.com/.../P159909). Why is such a singleton to be avoided?
Stefan's link might also be a little outdated. There's a new version of the Code Share page on here - community.progress.com/.../default.aspx - which links to it. Direct link is github.com/.../InjectABL . The github version has been updated to use some of the libraries in 11.4 (stuff which moved from AutoEdge into OE).
@ [mention:800c14aef8bc4aa3bcf9926cf50c8ff4:e9ed411860ed4f2ba0265705b8793d05] on where to start:
IoC containers all have the concept of a Composition Root, which is basically the top-level point at which the injection starts. Mark Seeman - who is a huge proponent of DI in the C#/.NET world - has a good intro at http://blog.ploeh.dk/2011/07/28/CompositionRoot/ . The point of the composition root is that it's the only place in the app that actually knows about the DI/IoC container. In AutoEdge it's in 1 file - start_session.p that is called in 2 places: on the client ABL code, from the start_ui.p procedure, and on AppServer startup, in as_startup.p (the startup event procedure).
@ [mention:5a647afc67ec4e118db4fd9337f8a264:e9ed411860ed4f2ba0265705b8793d05] on talks about this:
I have proposed talks on the use of interfaces and "Composing complex applications" for a few Exchanges and PUG/Challenges, without luck. There are, after all, only so many timeslots available.
I am always happy to talk about this stuff though. And even happier that Julian has finally seen the light on DI ;)
regards,
-- peter
edit: indicate who i'm talking to
Yeah yeah. Don't get too happy.. I'm still not entirely sure ☺
Answer me this.. If a method in a class is looping through, creating a temp table record and storing an instance of an object, surely the method must create it's own instance of the object, as there are multiple instances. In this case the instance cannot be injected into the class. So, what is?
[collapse]Reply by Peter JudgeStefan's link might also be a little outdated. There's a new version of the Code Share page on here - community.progress.com/.../default.aspx - which links to it. Direct link is github.com/.../InjectABL . The github version has been updated to use some of the libraries in 11.4 (stuff which moved from AutoEdge into OE).
IoC containers all have the concept of a Composition Root, which is basically the top-level point at which the injection starts. Mark Seeman - who is a huge fan of DI in the C#/.NET world - has a good intro at http://blog.ploeh.dk/2011/07/28/CompositionRoot/ . The point of the composition root is that it's the only place in the app that actually knows about the DI/IoC container. In AutoEdge it's in 1 file - start_session.p that is called in 2 places: on the client ABL code, from the start_ui.p procedure, and on AppServer startup, in as_startup.p (the startup event procedure).
I have proposed talks on the use of interfaces and "Composing complex applications" for a few Exchanges and PUG/Challenges, without luck. There are, after all, only so many timeslots available.
I am always happy to talk about this stuff though. And even happier that Julian has finally seen the light on DI ;)
regards,
-- peter
Stop receiving emails on this subject.Flag this post as spam/abuse.
Yeah yeah. Don't get too happy.. I'm still not entirely sure ☺
Answer me this.. If a method in a class is looping through, creating a temp table record and storing an instance of an object, surely the method must create it's own instance of the object, as there are multiple instances. In this case the instance cannot be injected into the class. So, what is?
Stefan's link might also be a little outdated. There's a new version of the Code Share page on here - community.progress.com/.../default.aspx - which links to it. Direct link is github.com/.../InjectABL . The github version has been updated to use some of the libraries in 11.4 (stuff which moved from AutoEdge into OE).
IoC containers all have the concept of a Composition Root, which is basically the top-level point at which the injection starts. Mark Seeman - who is a huge fan of DI in the C#/.NET world - has a good intro at http://blog.ploeh.dk/2011/07/28/CompositionRoot/ . The point of the composition root is that it's the only place in the app that actually knows about the DI/IoC container. In AutoEdge it's in 1 file - start_session.p that is called in 2 places: on the client ABL code, from the start_ui.p procedure, and on AppServer startup, in as_startup.p (the startup event procedure).
I have proposed talks on the use of interfaces and "Composing complex applications" for a few Exchanges and PUG/Challenges, without luck. There are, after all, only so many timeslots available.
I am always happy to talk about this stuff though. And even happier that Julian has finally seen the light on DI ;)
regards,
-- peter
Flag this post as spam/abuse.
Flag this post as spam/abuse.