do you inject ?

Posted by jmls on 04-Oct-2014 11:51

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 ?

All Replies

Posted by jmls on 04-Oct-2014 11:55

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 !

Posted by bronco on 04-Oct-2014 12:01

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.

Posted by Mike Fechner on 04-Oct-2014 12:06

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.

 

Posted by jmls on 04-Oct-2014 12:08

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

Posted by jmls on 04-Oct-2014 12:09

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

Posted by bronco on 04-Oct-2014 12:34

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.

Posted by jmls on 04-Oct-2014 12:42

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

Posted by Mike Fechner on 04-Oct-2014 13:05

Does not need to call into a factory. It might call into a registry and let the registry care about when/why/how the actual object will be created/had been created.
 

Posted by bronco on 04-Oct-2014 13:51

Let's not get into a discussion what a Factory is or is not. (in Spring 2.0 XmlBeanFactory inherited from DefaultSingletonBeanRegistry)

Posted by Mike Fechner on 04-Oct-2014 13:56

J
Von: Bronco [mailto:bounce-bfvo@community.progress.com]
Gesendet: Samstag, 4. Oktober 2014 20:53
An: TU.OE.Architecture@community.progress.com
Betreff: RE: [Technical Users - OE Architecture Cloud and Arcade] do you inject ?
 
Reply by Bronco

Let's not get into a discussion what a Factory is or is not. (in Spring 2.0 XmlBeanFactory inherited from DefaultSingletonBeanRegistry)

Stop receiving emails on this subject.

Flag this post as spam/abuse.

Posted by bronco on 04-Oct-2014 14:03

btw Mike, are you on Iceland?

Posted by Mike Fechner on 04-Oct-2014 14:09

No, already passed that. A bit East of Boston as I see it. Real “cloud-computing”…

Posted by bronco on 04-Oct-2014 14:29

haha, I should have known.

Posted by jmls on 05-Oct-2014 09:26

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.


Posted by bronco on 07-Oct-2014 06:39
Posted by jmls on 07-Oct-2014 12:17

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

  • is this passed into the calling object to pass to HomeController ? If so, at what point do you stop  - should the initial entry point to the application know about *every* class in the system ? How does this class know that class C (called from class B, called from class A, called from this root) needs a foobar widget ?
  • is the servicefactory instance created by the calling object ? If so, isn;t that closely binding the two objects together ? (calling object and the service factory)
  • what if I need to use several objects in HomeController  ? Should they be passed as several factory parameters to the constructor - or one factory ?
  • are we missing a proper DI framework in progress ?

Posted by bronco on 07-Oct-2014 13:03

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

Posted by bronco on 07-Oct-2014 13:08

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)

Posted by bronco on 07-Oct-2014 14:15

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. 

Posted by agent_008_nl on 08-Oct-2014 01:53

>  we don't have a proper DI framework in openedge

Isn't this a proper one: github.com/.../InjectABL

Posted by agent_008_nl on 08-Oct-2014 02:03

> 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?

Posted by jmls on 08-Oct-2014 02:07

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

Posted by agent_008_nl on 08-Oct-2014 02:29

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

Posted by agent_008_nl on 08-Oct-2014 02:55

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).

Posted by agent_008_nl on 08-Oct-2014 02:57

Could be a nice session on pugchallenges: Peter Judge on these matters, with an injectABL demo.

Posted by Mike Fechner on 08-Oct-2014 04:45

Peter Judge will be doing a nice evening session in BoF style on the habits of the highly effective programmer.
 
The idea is, that this will become a very vital discussion. And I guess he will also be able to talk about his DI implementation there…
 
 
There is still a week to register at normal price.
 
 
 

Posted by agent_008_nl on 08-Oct-2014 06:48

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.

Posted by Mike Fechner on 08-Oct-2014 06:57

Are you saying that you should have proposed the talk on that subject?

Von meinem Windows Phone gesendet

Von: agent_008_nl
Gesendet: ‎08.‎10.‎2014 07:48
An: TU.OE.Architecture@community.progress.com
Betreff: RE: [Technical Users - OE Architecture Cloud and Arcade] do you inject ?

Reply by agent_008_nl

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.

Stop receiving emails on this subject.

Flag this post as spam/abuse.

Posted by agent_008_nl on 08-Oct-2014 07:46

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.  

Posted by agent_008_nl on 08-Oct-2014 07:51

Oktoberfest in November is no problem for the Trifterner Blosn I suppose.

Posted by agent_008_nl on 08-Oct-2014 12:57

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?

blogs.msdn.com/.../140827.aspx "

Posted by Peter Judge on 16-Oct-2014 14:19

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

Posted by jmls on 16-Oct-2014 14:46

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]
On 16 Oct 2014 20:20, "Peter Judge" <bounce-pjudge@community.progress.com> wrote:
Reply by Peter Judge

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

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Peter Judge on 16-Oct-2014 14:59

There are, of course, some cases where you are going to instantiate your own objects. Depends what those objects are, though.  If the temp-table contains something which is an implementation of an instance, then you should use DI for resolving that interface type into an object, and your use of a tight loop might be wrong.
 
 
-- peter
 
 
[collapse]
From: jmls [mailto:bounce-jmls@community.progress.com]
Sent: Thursday, 16 October, 2014 15:47
To: TU.OE.Development@community.progress.com
Subject: RE: [Technical Users - OE Development] do you inject ?
 
Reply by jmls

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?

On 16 Oct 2014 20:20, "Peter Judge" <bounce-pjudge@community.progress.com> wrote:
Reply by Peter Judge

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

Stop receiving emails on this subject.

Flag this post as spam/abuse.

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

This thread is closed