tl;dr - what cedric says. Basically this is a perfectly reasonable pattern.

The thing I always try to keep in mind is to segregate the things i'm injecting into "services/collaborators", configuration, and value types (consumables). The former I always inject, the middle I usually inject, the latter I nearly never inject, and pass in as function parameters on the call-stack, and create with factories.

As Cedric points out, it's a good pattern for keeping things clear. This is where judgment and having made a lot of mistakes comes in. They are design aesthetics and judgment calls. But as you described your code, it's reasonable. I prefer this to overloading the Provider<T> type and using custom scopes, which some do in this sort of case.

The important criterion here is the life-span and validity of any given object relative to the ingredients of its construction and the circumstances of its use. You're making arbitrary connections based on parameters - elements that seem to have very temporary existence. So your connection can't be any longer-lived than those parameters, since it must be created with them. But the factory, and other services associated with creating a connection may well have no short-lived dependencies, so can be part of the "long-lived" object graph.

Christian.

On 20 Feb 2013, at 12:16, Cédric Beust ♔ wrote:

For what it's worth, this is exactly how I structure our code base: most of our types are either directly injected or they define an assisted factory:

class A {
public interface IFactory {
A create(String param);
}

@Inject
private A(@Assisted String param, Dependency1 dep1, Dependency2 dep2) {
// ...
}
}

I don't see anything wrong with this pattern (I did mention a weakness when it comes to inheritance on this list last week, look into the archives for
the discussion, but there is no clear answer to that one).

--
Cédric


--
Cédric



On Wed, Feb 20, 2013 at 7:10 AM, Bram <[email protected]> wrote:

I'm experiencing some problems with implementing Guice / DI in the proper way. I end up creating allot of a factories because I need objects with specific settings that I only know at runtime. As an example, imaging the
following:

A connection object that can send/receive "something" and connects to a
host:port:

public Connection(String host, int port);

A http client that needs a connection:

public HttpClient(Connection connection);


Now, when I need a HttpClient in one of my objects (for example, a
crawler) I can't magically get that injected with the correct settings
(host/port). What I end up doing is creating factories for both the
Connection and the HttpClient:

public interface ConnectionFactory {
public Connection create(String host, int port);
}

public interface HttpClientFactory {
public HttpClient create(Connection connection);
}

And my constructors then look like this:

public Connection(@Assisted String host, @Assisted int port);
public HttpClient(@Assisted Connection connection);

And I have to inject both factories in, for example, my webcrawler to be
able to get a HttpClient:

class WebCrawler {
private final HttpClientFactory httpClientFactory;
private final ConnectionFactory connectionFactory;

@Inject
public WebCrawler(HttpClientFactory  httpClientFactory,
ConnectionFactory connFactory) {}

public void someMethod() {
Connection conn = connectionFactory.create(host, port);
HttpClient client = httpClientFactory.create(conn);
....
}
}

With this, everything is injectable and "loosly" coupled, but I have the feeling I'm missing the point somewhat. Instead of doing Connection = new Connection(..) i changed everything to xxFactory.create(..) and I have allot of factories injected in my classes. A second approach would be to inject the connection factory into the HttpClient but that also smells as
"not the way to do it".

What am I not seeing?

--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




--
You received this message because you are subscribed to the Google Groups "google-guice" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Christian Gruber :: Google, Inc. :: Java Core Libraries :: Dependency Injection
email: [email protected] :::: mobile: +1 (646) 807-9839

--
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to