为循环内的instanciated类型注入依赖项

时间:2014-10-03 22:17:11

标签: java dependency-injection

我想在这种情况下使用Implementation的依赖注入:

public interface Implementable{[...]}
public class Implementation implements Implementable{[...]}

public class DummyClass()
{
    private List<Implementable> testList;
    public DummyClass()
    {
        testList = new ArrayList<Implementable>();
        for(int i = 0; i < 10; i++)
        {
            Implementable testVar = new Implementation(i);
            testList.add(testVar);
        }
    }
}

尽管我设法收集,但这是不可能的。既不是通过构造函数注入也不是使用泛型。另外,我更喜欢原生的解决方案,它不依赖于外部库来实现这一点。


修改 任何解决方案都要求DummyClass不必知道在循环中实例化InterfaceType的哪个实现。

我正在考虑使用泛型,但由于InterfaceType testVar = new T(i);不允许,因此失败了。此外,由于构造函数需要参数,newInstance()方法不可行。虽然这仍然是可能的,但它需要过多的反思(getConstructor)和类型安全性的损失,因为我尝试了干净的方法。

我非常满意地听到我想要实现的目标无法以任何可推荐的方式完成。这个问题是希望我确实错过了一些东西。


EDIT2: 我试图采用类似于drewmoore提供的解决方案,但遇到了一个我没有想过的缺陷。

接口不会声明构造函数的任何要求。使用这种方法,我必须在接口的所有实现中使用相同的构造函数。

这让我想到了构建器模式。其中仍然存在与界面需要定义构建方法相同的警告,因此再次必须对如何构建所有实现提出要求。

延迟施工还有其他方法吗?也就是说,这种方法可以让我注入我想要使用的实现的实例(public DummyClass(InterfaceType implementation)),但只在循环中构造(或构建或初始化)它然后返回自身的副本。

但话又说回来。我越来越觉得我想要实现的目标是不可能实现的。或者由于不合理的额外复杂性或强加的限制,它不应该被完成。然后我可能会接受这个类对实现的直接依赖,并感谢drewmoore的见解。

1 个答案:

答案 0 :(得分:0)

在给出了这个进一步的思考并受到现在不幸删除的drewmoore答案的启发后,我得出了以下结论:

虽然我对使用界面宣布施工合同感到不安,但正如我在第二次编辑中所述,我现在意识到这正是情况所需要的。我的意思是能够在循环内以某种方式构造这个对象。因此,必须制定该循环所需的要求。当然,界面非常适合这项工作。

以最初的例子为例,我的解决方案如下:

DummyClass dummyInstance = new DummyClass(new ImplementationProvider());

///////

public interface Implementable{[...]}
public class Implementation implements Implementable{[...]}

public interface ImplementationProviderAware
{
    public Implementable createImplementation(Integer counter);
}

public class ImplementationProvider implements ImplementationProviderAware
{
    public Implementable createImplementation(Integer counter)
    {
        return new Implementation(counter);
    }
}

public class DummyClass(ImplementationProviderAware implementationProvider)
{
    private List<Implementable> testList;
    public DummyClass()
    {
        testList = new ArrayList<Implementable>();
        for(int i = 0; i < 10; i++)
        {
            Implementable testVar = implementationProvider.createImplementation(i);
            testList.add(testVar);
        }
    }
}