首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在包含大量需要动态生成其他类的类的项目中注入依赖项

在包含大量需要动态生成其他类的类的项目中注入依赖项
EN

Stack Overflow用户
提问于 2011-04-03 04:22:41
回答 1查看 302关注 0票数 1

我正在开发一种从A语言到B语言的翻译器(是的,它有点像编译器)。翻译通常来自几个不同的文件,每个文件都有相同的3个部分要翻译。所以,在我这样做的时候,我是这样做的:

当我实例化一个转换器并为其提供一些数据时,它将需要生成所有需要的FileTranslator类。因为我不应该在Translator中做new,所以我应该从上面请求一个工厂。在翻译器部分中也发生了同样的事情。这就带来了一个问题,那就是我不得不创建很多样板工厂。此外,每个翻译器可能需要更多的工厂来生成一些他们可能想要使用的其他类。

我是不是想错了,还是就是这样?顺便说一下,我不允许在这个项目中使用任何类型的DI/IoC框架。

编辑:

我担心我的信息不能被传达出去。

在这个特定的例子中,因为我的Translator类需要能够随时生成一些FileTranslator,所以它需要一个FileTranslatorFactory。我知道我可以让一个IoC容器为我做连接,但是IoC容器本身不会让我省去编写FileTranslatorFactory本身代码的麻烦。我说的对吗?

现在的问题是,FileTranslator还必须能够在需要SectionATranslators、SectionBTranslators和SectionCTranslators时生成(不要认为它们有任何相似之处,因为它们的名称是--它们完全不同,彼此没有任何关系!)。因此,我必须为它们中的每一个定义工厂。因此,对于这样一个简单的5类系统,我需要创建4个(!)工厂。

因为我不希望我的域对象依赖于IoC-Container,并且我不想为所有4种似乎需要IoC-Container的对象都有一个工厂,我还缺少什么吗?

EN

回答 1

Stack Overflow用户

发布于 2011-04-03 05:13:04

事实上,在为类层次结构手动创建依赖注入时涉及到大量样板代码,这就是框架存在的原因。对不起,除非您能让那些决定使用无DI/IoC框架规则的人改变主意,否则您要么编写大量的样板代码,要么自己编写一个框架。

编辑-使用一个完全虚构的框架,使其尽可能保持不可知,但解释如何在许多情况下消除对容器的所有调用,只保留一个调用。

因此,使用如下的Translator实现:

代码语言:javascript
复制
public class Translator
{
    private ITranslator translatorInstance;

    public Translator()
    {
        SomeContainer container = SomeContainer.CreateFromConfig(configFilePath);

        // this is the ONLY point we touch the container
        translatorInstance = container.GetMeA<ITranslator>();
    }

    // implementation
}

我们可以看到,它作为一个工厂工作,并且是唯一需要了解容器本身的类。因此,ITranslator的一个具体实现者的实现可以是:

代码语言:javascript
复制
public class FileTranslator : ITranslator
{
    // private fields

    public FileTranslator(  ISectionATranslator sectionAtrans, 
                            ISectionBTranslator sectionBtrans, 
                            ISectionCTranslator sectionCtrans)
    {
        this.sectionAtrans = sectionAtrans;
        // etc
    }

    // implementation
}

注意,FileTranslator不知道哪些具体的类实际实现了它所依赖的接口,也不需要任何类型的工厂。实际上,容器将为您完成此操作。容器有几种方法来解决这个问题,一个例子是显式配置,类似于:

代码语言:javascript
复制
<!-- absolutely fictitious configuration file, but similar to many frameworks -->
<ContainerConfig>
    <ObjectResolver interface="ITranslator">
        <ConcreteType type="FileTranslator">
            <ConstructorInjection>
                <Argument ordinal="0" type="SectionATranslator" />
                <Argument ordinal="1" type="SectionBTranslator" />
                <Argument ordinal="2" type="SectionCTranslator" />
            </ConstructorInjection>
        </ConcreteType>
    </ObjectResolver>
</ContainerConfig>

许多框架甚至不需要你定义特定的构造函数参数,你只需声明如果你想要一个ISectionATranslator,那么返回一个SectionATranslator,它会在调用构造函数之前自动创建这些参数。

还要注意,有些框架提供了在代码中使用fluent风格的API定义这些类型解析规则的选项,有些框架允许您通过某个名称(可能是"Production"实现与"UnitTest"实现)定义多种可能的方式来解析特定类型。

请注意,我故意将上述内容含糊其辞,因为我不想说哪个框架是最好的(老实说,我认为这取决于您的个人需求)-请在StackOverflow上的其他地方查看框架比较,并请尝试一些(也许您可以尝试一些而不告诉您的老板!)。不过,希望上面的内容能够说明为什么IoC容器可以消除对工厂类层层的需求,从而使您的代码更加简洁。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5525628

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档