Discussion:
How to apply DI to this situation
Almas1997
2008-06-16 07:56:27 UTC
Permalink
Hi guys,

I have a question about applying of DI in this case.

I wrote a class (its a pseudocode :) and want to create an object in its
some method using container.

class ClassA
{
public ClassA()
{
}

public void SomeMethod()
{
// want to create an instance of classB here using container
}
}

class ClassB : IDisposable
{
}

I could find only two solutions how to implement it.

// 1
class ClassA
{
private PicoContainer pico;
public SomeClass(PicoContainer pico)
{
this.pico = pico;
}

public void SomeMethod()
{
using (var b = pico.getComponent(typeof(classB))
{
}
}
}

In that case i should inject container, but it's anti-pattern according to
the documentation :(

// 2
class ClassA
{
private IClassBFactory factory;

public SomeClass(IClassBFactory factory)
{
this.factory = factory;
}

public void SomeMethod()
{
using (var b = factory.CreateInstance())
{
}
}
}

In that case i can inject class factory for class B. But i want to use a
container to create instances, not factory.

So both my solutions have limitations.
And I'd like to know what will be the most correct solving of this problem.

Thank you in advance.
--
View this message in context: http://www.nabble.com/How-to-apply-DI-to-this-situation-tp17859690p17859690.html
Sent from the NanoContainer - PicoContainer - Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Jörg Schaible
2008-06-16 09:35:27 UTC
Permalink
Hi,
Post by Almas1997
Hi guys,
I have a question about applying of DI in this case.
I wrote a class (its a pseudocode :) and want to create an object in
its some method using container.
class ClassA
{
public ClassA()
{
}
public void SomeMethod()
{
// want to create an instance of classB here using container }
}
class ClassB : IDisposable
{
}
I could find only two solutions how to implement it.
// 1
class ClassA
{
private PicoContainer pico;
public SomeClass(PicoContainer pico)
{
this.pico = pico;
}
public void SomeMethod()
{
using (var b = pico.getComponent(typeof(classB)) {
}
}
}
In that case i should inject container, but it's anti-pattern
according to the documentation :(
// 2
class ClassA
{
private IClassBFactory factory;
public SomeClass(IClassBFactory factory)
{
this.factory = factory;
}
public void SomeMethod()
{
using (var b = factory.CreateInstance())
{
}
}
}
In that case i can inject class factory for class B. But i
want to use a
container to create instances, not factory.
So both my solutions have limitations.
And I'd like to know what will be the most correct solving of this problem.
Thank you in advance.
It's a variant to your case 1. Let your main class implement a ServiceLocator interface and let ClassA depend on the ServiceLocator:

class Main implements ServiceLocator {
// implement ServiceLocator.getClassBInstance()
ClassB getClassBInstance() {
return (ClassB)pico.getInstance(ClassB.class);
}
}

class classA {
ServiceLocator locator;
classA(ServiceLocator locator) {
this.locator = locator;
}
}

- Jörg

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Almas1997
2008-06-16 09:47:06 UTC
Permalink
Post by Jörg Schaible
It's a variant to your case 1. Let your main class implement a
class Main implements ServiceLocator {
// implement ServiceLocator.getClassBInstance()
ClassB getClassBInstance() {
return (ClassB)pico.getInstance(ClassB.class);
}
}
class classA {
ServiceLocator locator;
classA(ServiceLocator locator) {
this.locator = locator;
}
}
Thank you. But in that case your Main class still has container dependency.
--
View this message in context: http://www.nabble.com/How-to-apply-DI-to-this-situation-tp17859690p17861159.html
Sent from the NanoContainer - PicoContainer - Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Jörg Schaible
2008-06-16 10:20:19 UTC
Permalink
Post by Almas1997
Post by Jörg Schaible
It's a variant to your case 1. Let your main class implement a
class Main implements ServiceLocator {
// implement ServiceLocator.getClassBInstance() ClassB
getClassBInstance() { return
(ClassB)pico.getInstance(ClassB.class); }
}
class classA {
ServiceLocator locator;
classA(ServiceLocator locator) {
this.locator = locator;
}
}
Thank you. But in that case your Main class still has
container dependency.
No, since this is normally the class that sets up the container:

class Main implements ServiceLocator {
PicoContainer pico;
Main() {
pico = new DefaultPicoContainer();
pico.registerInstance(this);
// ....
}
}

And this is normally the only class that references a class from the complete PicoContainer framework at all (well, unless you have chosen to use the default lifecylce provided by Pico where you will have to derive from the LC interfaces).

- Jörg

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Paul Hammant
2008-06-16 12:42:22 UTC
Permalink
This is the key. The anti-pattern only applies to components and each-
other.

There's always going to be some boot code that sets up the
container(s), it has to be aware of containers and components. Just
be sure that you're propagating containers into components :-)



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Almas1997
2008-06-16 16:45:02 UTC
Permalink
Thank you.

As i understand correctly, somewhere in the apllication should be a global
reference to the Main class instance, so that i can have access to the
container. Or Main class should be a singleton?
Which is correct structure of this boot class and access to the container?
Post by Jörg Schaible
Post by Almas1997
Post by Jörg Schaible
It's a variant to your case 1. Let your main class implement a
class Main implements ServiceLocator {
// implement ServiceLocator.getClassBInstance() ClassB
getClassBInstance() { return
(ClassB)pico.getInstance(ClassB.class); }
}
class classA {
ServiceLocator locator;
classA(ServiceLocator locator) {
this.locator = locator;
}
}
Thank you. But in that case your Main class still has
container dependency.
class Main implements ServiceLocator {
PicoContainer pico;
Main() {
pico = new DefaultPicoContainer();
pico.registerInstance(this);
// ....
}
}
And this is normally the only class that references a class from the
complete PicoContainer framework at all (well, unless you have chosen to
use the default lifecylce provided by Pico where you will have to derive
from the LC interfaces).
--
View this message in context: http://www.nabble.com/How-to-apply-DI-to-this-situation-tp17859690p17868547.html
Sent from the NanoContainer - PicoContainer - Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Paul Hammant
2008-06-16 16:59:31 UTC
Permalink
Not always.

See https://svn.codehaus.org/picocontainer/java/sandbox/swing_mvc_example/src/java/com/sun/example/mvc/Main.java

This main() methods exists and the container's it made are possibly
eligible for garbage collection. This works because Swing makes a new
thread that handles events that work on the components made by the
container.

- Paul
Post by Almas1997
Thank you.
As i understand correctly, somewhere in the apllication should be a global
reference to the Main class instance, so that i can have access to the
container. Or Main class should be a singleton?
Which is correct structure of this boot class and access to the container?
Post by Jörg Schaible
Post by Almas1997
Post by Jörg Schaible
It's a variant to your case 1. Let your main class implement a
ServiceLocator interface and let ClassA depend on the
class Main implements ServiceLocator {
// implement ServiceLocator.getClassBInstance() ClassB
getClassBInstance() { return
(ClassB)pico.getInstance(ClassB.class); }
}
class classA {
ServiceLocator locator;
classA(ServiceLocator locator) {
this.locator = locator;
}
}
Thank you. But in that case your Main class still has
container dependency.
class Main implements ServiceLocator {
PicoContainer pico;
Main() {
pico = new DefaultPicoContainer();
pico.registerInstance(this);
// ....
}
}
And this is normally the only class that references a class from the
complete PicoContainer framework at all (well, unless you have chosen to
use the default lifecylce provided by Pico where you will have to derive
from the LC interfaces).
--
View this message in context: http://www.nabble.com/How-to-apply-DI-to-this-situation-tp17859690p17868547.html
Sent from the NanoContainer - PicoContainer - Users mailing list archive at Nabble.com.
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Continue reading on narkive:
Loading...