sindi and mocking

19 views
Skip to first unread message

david roon

unread,
Feb 21, 2012, 8:47:29 AM2/21/12
to sindi-users
Hi Alois,
So I tried sindi and it looks very nice. I went for the constructor
pattern at first but I have to say I prefer by far the component
approach.

But here is my issue. Let's imagine you have 10 services: ServiceA0..9
and each of them depends on ServiceB
So for each ServiceAk I'll create a component ServiceAkComponent and
bind my service with ServiceAkImpl with ServiceBComponent

Until here everything is fine.

Now let's imagine that I want to mock ServiceB or use a different
implementation. But I don't want to rewrite all the ServiceA0..9
components because it would take too much time and effort for not
much. How should I do that?

I am coming from Guice and there, you simply add the MockModule to the
injector and the mocked implementation will be injected instead of the
real implementation.

Thank you in advance!

Alois Cochard

unread,
Feb 22, 2012, 7:22:26 AM2/22/12
to sindi-users
Hello David!

Thanks for your feedback :)

Could you please take a look at this small mocking example and tell me
if it suit your needs:
https://gist.github.com/1884581

If not, could you please try to fork it to show what you really mean?

As you will see, I added in this example a pattern to avoid polluting
core application code with Sindi dependencies.

Anyway I personally prefer the Component approach over constructor
injection too, but it should be noted that my last effort in trunk
(0.5-SNAPSHOT) removed constructor autowiring support in favor of
functions autowiring only.
I've just finished implementing it on the compiler side, and
autowiring support is now complete and can be seen as an alternative
to Component (even if I still prefer Component style! which is a kind
'super' cake pattern).

Looking forward your feedback!

Cheers,

david roon

unread,
Feb 22, 2012, 7:47:22 AM2/22/12
to sindi-users
I am not sure yet how to change the code to explain what I mean.

The issue I see, and let me know if I misunderstood something, is the
fact that you have to tell from which module you take your elements.
In the IoCs I know from Java, what you should tell is what you want
rather than from where.
For example,
If you have all your services that depend on a logging service, then I
would like each component to be able to say "I want the logging
service" without taking care of the source. It could be a file logger,
a db logger or a System.out logger.
I think my issue is that I am use to get the instances from the
context and therefore I am use to see the context doing the wiring but
it seems here the modules are doing it.

My approach right now is the following:
I define together a Component + Module + Trait + Implementation trait
On each module I compose them with the components they need so it is
also very easy to understand what is going on.

But the issue with this approach is that it is impossible to tell the
module to use another implementation. For example, I want the context
to inject TestLogger instead of DBLogger during my tests. But because
I use the components I don't see how to do that efficiently.
Again I love the components idea because it makes it very clear what
is being used. But I fail to see how to make it modular as well.

Now that I think about it, tell me if I am right. What I should do is
to have two main modules:
Prod and Dev
Then for each Service I create two Components, one for prod and one
for dev. and then in my context, I can map which component I want and
I can mock whatever I want. Also, this way I can decide to take
ServiceA from Prod and ServiceB from Dev or both from Dev etc etc.

I think my issue was the concept of Module. I will try what I just
explained and I'll let you know.
Please tell me what you think about the idea.

david roon

unread,
Feb 22, 2012, 8:32:22 AM2/22/12
to sindi-users
I just got another Idea. I am trying it right now but I have one
issue.

The idea is to use structural types to define the components.

What I do is for each component. I define it that way:


trait MyComponent[T <:Module{def serviceA:ServiceA}]{
def serviceA = from[T].serviceA
}

This way I can easily define which component should use which module
and therefore be more flexible.
The issue I get is that it tells me that no Manifest is defined for T.
And I am too bad at Scala to know exactly what to do with this.

Let me know what you think

Alois Cochard

unread,
Feb 22, 2012, 4:45:53 PM2/22/12
to sindi-users
Hello David,

I have just created an example showing how to implement logging using
Sindi, I don't show how to use global context but if you don't need
it, it should be avoided.
Global context could be useful when integrating with some framework
where you can't have control on service instantiation (e.g.
integrating Component on Lift snippet).

During my experimentation I found a *ugly* bug with module scoping, I
just fixed it but this imply some change in module definition (in fact
it's a regression, I wasn't able to catch it due to lack of test,
which is hopefully not the case anymore).

Here is the example: https://github.com/aloiscochard/sindi/tree/0.5/sindi-examples/demo

As you see it use version 0.5, please upgrade, and look at this
example (or documentation) to see the small changes in module
definition and import.

Looking forward your feedback,

PS: Component are tied to module (or context in some case) bindings,
you shouldn't make component "dynamic" sort to say, but you can make
them dynamic by overriding the binding of corresponding module, I hope
this example will show you how to do that. Don't hesitate to ask for
clarification. (keep in mind Sindi's Module are not the same as Guice
Module, it's better trying to forgot the meaning module as in Guice,
in fact I plan to add this kind of information here
https://github.com/aloiscochard/sindi/wiki/Comparison but hadn't time
to do so yet).

Alois
Reply all
Reply to author
Forward
0 new messages