0

我来自 .NET 领域,最近正在做一些 Java 项目(将 .NET 代码库的一部分转换为 Java)。通常我使用 .NET 和 Castle Windsor 作为我选择的 IoC 容器并且我非常熟悉它。我正在将 PicoContainer IoC 容器用于 Java 项目,并且正在尝试弄清楚如何将作用域依赖项注入到容器中。通过“范围依赖”,我的意思是一个依赖,只要容器的“范围”是开放的,每次从容器中解析依赖时,结果都是完全相同的对象。

在 .NET 领域,使用诸如 Castle Windsor 之类的 IoC 容器,注册具有特定生命周期(Singleton、Transient、Scoped 等)的组件是微不足道的。例如,以下 C# 可以按预期完美运行。

// C#代码 //

IWindsorContainer container = new WindsorContainer();
container.Register(Component
    .For<Foo>()
    .ImplementedBy<FooImpl>()
    .LifestyleScoped()
);
using (container.RequireScope())
{
    Foo foo1 = container.Resolve<Foo>();
    Foo foo2 = container.Resolve<Foo>();
    Console.WriteLine(foo1 == foo2); // Will print true
    Console.WriteLine(foo1.Equals(foo2)); // Will print true
}

public interface Foo
{

}

public class FooImpl : Foo
{

}

然而,在 Java 领域,使用像 PicoContainer 这样的 IoC 容器,似乎没有办法实现这种我觉得很奇怪的行为。

// JAVA代码 //

PicoContainer container = new DefaultPicoContainer();
container.addComponent(FooImpl.class);

// FooImpl implements an interface called "Foo" (for clarity & brevity)
Foo foo1 = container.getComponent(Foo.class);
Foo foo2 = container.getComponent(Foo.class);

// How to "scope" PicoContainer"?
// It appears the default behavior of DefaultPicoContainer is "scoped"...
// I could not find any documentation clarifying one way or another though

System.out.println(foo1 == foo2); // Should print true (most likely), for reference equality, but it does not.
System.out.println(foo1.equals(foo2)); // Should print true, for object equality, but it does not.

public interface Foo
{

}

public class FooImpl extends Foo
{

}

我确信它必须具有这样的功能,因为我无法想象有人使用 IoC 容器并希望每个依赖项都是瞬态的或仅是单例的。

现在,在发布这个问题之前,我确实彻底查阅了以下链接中的文档以及谷歌的解决方案,但似乎没有任何帮助:

http://picocontainer.com/lifecycle.html http://picocontainer.com/javadoc/core/org/picocontainer/DefaultPicoContainer.html http://picocontainer.com/javadoc/core/org/picocontainer/lifecycle/DefaultLifecycleState。 html

似乎没有这样的生活方式(或相关的 API)选项来允许 PicoContainer 中的范围依赖。我能想到的一些解决问题的想法是一个临时容器(或主容器的子容器),它包含像作用域依赖项一样的“临时单例”,一旦调用代码完成子容器,它将调用某种在持有“临时单身人士”的子容器上使用“处置”方法并将它们全部清除。然而,据我所知,这似乎不优雅而且相当“hacky”。

另一个解决方案可能存在于 PicoContainer 的“启动”和“停止”API 中,但这些对我来说没有意义,因为我不理解 IoC 容器“启动”和“停止”的概念,而只是“现有” (或不)。此外,文档还不清楚各种依赖项是否需要实现此类方法/API。这种用例似乎……不直观?或者更确切地说,就像我们鼓励将抽象/NFC 耦合和泄漏到依赖项中一样。我怀疑这就是那些 API 的用途,所以我可能在这里走错了路。

PS 我不同意使用 PicoContainer 作为该项目选择的 IoC 容器的想法。如果它们可以实现 IoC 容器功能,我愿意接受其他选择。我对“Guice”做了一些简单的初步调查,但它似乎不是传统 IoC 容器意义上的“容器”,而是一个具有有限注入器的库,并且完全依赖于依赖解析的注释。我正在寻找更接近传统 IoC 容器(例如 Castle Windsor)所期望的东西。

感谢您的任何见解或帮助!

4

0 回答 0