For my current app, I am not using a bean factory. I don't need nor want one (for now). FW1 is especially well suited for this, since it auto-caches your services for you, and let's you access them using service(), without having to list them somewhere yourself.
Where you start to run into problems, however, is if you need to use the result of one service in another service. You can't do this by using the startItem(), item(), endItem() constructs with service(), because no matter where you queue up the service, they will always run at the same time, and once they run, giving you the result you need, you can no longer queue up other services.
The only solution is to bypass the service queuing system, by invoking one or both of your services directly, without using service(), as the FW1 example apps do often. But how do you get to your services? When you use service(), FW1 uses it's snazzy, auto-generated internal collection of your services. If you don't use service(), however, FW1 doesn't expose its snaz-collection in any way, so you have to roll your own. You have to start introducing ColdSpring or DI/1, or at minimum just listing your services in app scope - essentially duplicating what FW1 has already done.
Instead of adding all that kludge, I decided to simply make getService()public, and it seems to neatly solve all the problems:
Any reason why I have to be sneaking around the seedy underbelly of society to achieve this? What do you guys think of exposing some methods to get at the collection of services?
You are better off creating a very lightweight bean factory that implements the couple of methods that FW/1 needs -- it can then just act as a "bucket of services" in the way you want without having to break the standard framework.
I have talked about the one I made on this list before, but you can grab the code here:
I then use my "registerService" method to stick references to my services into my beanFactory. From there you can do what FW/1 expects, including using getBeanFactory() yourself.
I take a shortcut by doing this in the init() method of a baseController that all my controllers extend:
> For my current app, I am not using a bean factory. I don't need nor want > one (for now). FW1 is especially well suited for this, since it > auto-caches your services for you, and let's you access them using > service(), without having to list them somewhere yourself.
> Where you start to run into problems, however, is if you need to use the > result of one service in another service. You can't do this by using the > startItem(), item(), endItem() constructs with service(), because no > matter where you queue up the service, they will always run at the same > time, and once they run, giving you the result you need, you can no > longer queue up other services.
> The only solution is to bypass the service queuing system, by invoking > one or both of your services directly, without using service(), as the > FW1 example apps do often. But how do you get to your services? When you > use service(), FW1 uses it's snazzy, auto-generated internal collection > of your services. If you don't use service(), however, FW1 doesn't > expose its snaz-collection in any way, so you have to roll your own. You > have to start introducing ColdSpring or DI/1, or at minimum just listing > your services in app scope - essentially duplicating what FW1 has > already done.
> Instead of adding all that kludge, I decided to simply make getService() > public, and it seems to neatly solve all the problems:
> Any reason why I have to be sneaking around the seedy underbelly of > society to achieve this? What do you guys think of exposing some methods > to get at the collection of services?
> You are better off creating a very lightweight bean factory that > implements the couple of methods that FW/1 needs
It's not hard to get around the issue, I definitely don't think I'm better off though. I mainly would like to know why using my service on my own time is worse than using the exact same service on FW1's schedule.
There's no reason to use queued services if that doesn't feel right for your app (it seems few do), but I was talking specifically about being "better off" with a beanfactory than changing the underlying framework. Otherwise, you might as well just cache your own singletons in the application scope and call them that way from your controllers.
My point was simply that FW/1 already provides an easy way to do that while doing things within the framework conventions -- and doing that might pay off down the road idiomatically and for readability.
> You are better off creating a very lightweight bean factory that > implements the couple of methods that FW/1 needs
> It's not hard to get around the issue, I definitely don't think I'm > better off though. I mainly would like to know why using my service on > my own time is worse than using the exact same service on FW1's schedule.
On Sun, Feb 26, 2012 at 12:59 PM, Baz <b...@thinkloop.com> wrote: > introducing ColdSpring or DI/1, or at minimum just listing your services in > app scope - essentially duplicating what FW1 has already done.
DI/1 and ColdSpring do something very different - they manage dependencies between elements of the model.
Once you move away from service queuing, you will find the interim period before you _need_ that dependency management is very short. That's why getService() is not public - it's use should not be encouraged because auto wiring via a DI / bean factory is a much better solution and you'll need it anyway. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/
"Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880)
How does queuing services or not relate to whether they may need dependency management? They seem to be two separate things. I could have very complex services whose function calls are queued, or whose functions are called directly. And I could have simple services that may need to be called directly, or are better off queued. I'm not seeing how the complexity of a service relates to how I want to invoke its methods.
I'm really asking to get a better understanding.
Is it perhaps that the whole queuing of services is not that great? First they happened automatically, now by default implicit services are off, maybe in the next version we just get rid of queuing services and service management all together? Mapping service functions to controller functions isn't that great a practice imho.
Thanks, Baz
On Tue, Feb 28, 2012 at 6:52 PM, Sean Corfield <seancorfi...@gmail.com>wrote:
> On Sun, Feb 26, 2012 at 12:59 PM, Baz <b...@thinkloop.com> wrote: > > introducing ColdSpring or DI/1, or at minimum just listing your services > in > > app scope - essentially duplicating what FW1 has already done.
> DI/1 and ColdSpring do something very different - they manage > dependencies between elements of the model.
> Once you move away from service queuing, you will find the interim > period before you _need_ that dependency management is very short. > That's why getService() is not public - it's use should not be > encouraged because auto wiring via a DI / bean factory is a much > better solution and you'll need it anyway. > -- > Sean A Corfield -- (904) 302-SEAN > An Architect's View -- http://corfield.org/ > World Singles, LLC. -- http://worldsingles.com/
> "Perfection is the enemy of the good." > -- Gustave Flaubert, French realist novelist (1821-1880)
The take-way: basically forget about the service() architecture completely. The fact that it's there and provides basic service management is an anomaly.
From Sean:
"I have abandoned the concept of queuing up service calls completely for FW/1 on Clojure"
"If I had the chance to do FW/1 over from scratch, I would not implement the services convention - I would push people to a single model/ folder and encourage folks to manage service calls directly, using a simple DI framework (so I would have made DI/1 a couple of years earlier :) "
This makes sense to me. I really would vote to get rid of it next version, or at least make it much less prominent in the docs - I think it adds more confusion than it solves.
BTW, I really love FW1, I hope none of this comes off as derogatory.
On Tue, Feb 28, 2012 at 8:32 PM, Baz <b...@thinkloop.com> wrote: > How does queuing services or not relate to whether they may need > dependency management? They seem to be two separate things. I could have > very complex services whose function calls are queued, or whose functions > are called directly. And I could have simple services that may need to be > called directly, or are better off queued. I'm not seeing how the > complexity of a service relates to how I want to invoke its methods.
> I'm really asking to get a better understanding.
> Is it perhaps that the whole queuing of services is not that great? First > they happened automatically, now by default implicit services are off, > maybe in the next version we just get rid of queuing services and service > management all together? Mapping service functions to controller functions > isn't that great a practice imho.
> Thanks, > Baz
> On Tue, Feb 28, 2012 at 6:52 PM, Sean Corfield <seancorfi...@gmail.com>wrote:
>> On Sun, Feb 26, 2012 at 12:59 PM, Baz <b...@thinkloop.com> wrote: >> > introducing ColdSpring or DI/1, or at minimum just listing your >> services in >> > app scope - essentially duplicating what FW1 has already done.
>> DI/1 and ColdSpring do something very different - they manage >> dependencies between elements of the model.
>> Once you move away from service queuing, you will find the interim >> period before you _need_ that dependency management is very short. >> That's why getService() is not public - it's use should not be >> encouraged because auto wiring via a DI / bean factory is a much >> better solution and you'll need it anyway. >> -- >> Sean A Corfield -- (904) 302-SEAN >> An Architect's View -- http://corfield.org/ >> World Singles, LLC. -- http://worldsingles.com/
>> "Perfection is the enemy of the good." >> -- Gustave Flaubert, French realist novelist (1821-1880)
On Tue, Feb 28, 2012 at 9:13 PM, Baz <b...@thinkloop.com> wrote: > This makes sense to me. I really would vote to get rid of it next version, > or at least make it much less prominent in the docs - I think it adds more > confusion than it solves.
Yup. It was a failed experiment. The intent was to avoid boilerplate controllers that simply delegated to service calls - which I'd seen a lot in MVC code 2-3 years ago. Nowadays people don't make that mistake so much (they structure their controllers and services differently) so it's not a feature that's needed so much. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/
"Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880)
On Tue, Feb 28, 2012 at 8:32 PM, Baz <b...@thinkloop.com> wrote: > How does queuing services or not relate to whether they may need dependency > management?
The queuing mechanism was intended for simple service usage - you've already hit its limitations. In the simple world, DI is also not needed. As I said, by the time you hit the limitations with the simple queuing convention, you're only a short distance from also needing DI. That's the only connection. In other words, you run into both limitations around the same time in the grand scale of things.
> Is it perhaps that the whole queuing of services is not that great? First > they happened automatically, now by default implicit services are off, maybe > in the next version we just get rid of queuing services and service > management all together? Mapping service functions to controller functions > isn't that great a practice imho.