IoC,你把容器放在哪里? [英] IoC, Where do you put the container?

查看:27
本文介绍了IoC,你把容器放在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将城堡温莎用于我正在处理的宠物项目.我开始注意到我需要在代码的不同位置调用 IoC 容器来创建新对象.这种对容器的依赖使我的代码更难维护.

I'm using castle windsor for a pet-project I'm working on. I'm starting to notice that I need to call the IoC container in different places in my code to create new objects. This dependency on the container makes my code harder to maintain.

我用了两种解决方案来解决这个问题

There are two solutions I've used to solve this problem

我尝试创建抽象工厂作为容器的包装器,我可以将其注入到需要创建对象的应用程序部分中.这有效但有一些缺点,因为城堡很难将自己的容器作为依赖项注入.所以我必须手动完成,这违背了 IoC 容器的全部目的.

I tried to create abstract factories as wrappers around the container that I could inject into parts of my application that need to create objects. This works but has some drawbacks because castle has a hard time injecting it's own container as a dependency. So I have to do that by hand, this kind of defeats the whole purpose of the IoC container.

我使用了主 applicationcontroller 类来包装 IoC 容器并作为中央工厂/存储库工作.这是相当成功的,但这个类变得太大了,就像一个中心神对象,几乎所有其他对象都有一个引用.

I have used the main applicationcontroller class to wrap the IoC container and work as a central factory/repository. This was quite succesfull but this class is getting too big and acts like a central god-object, almost every other objects has a reference to it.

这两种解决方案都有效,但都有其缺点.所以我很好奇其他人是否遇到了同样的问题并找到了更好的解决方案.

Both solutions sort of work but both have their drawbacks. So I'm curious if other people had the same problem and have found better solutions.

编辑问题不在于依赖于对象 B 的对象 A.这里我通常只使用构造函数注入,一切正常.有时我有类型 A 的对象需要在它们的生命周期中创建可变数量的其他类型 B 的对象.我不知道该怎么做.

edit The problem isn't for object A that depends on object B. Here I usually just use constructor injection and everything works. Sometimes I have objects of type A that need to create a variable number of other objects of type B during their lifetime. I'm not sure how to do this.

@Blair Conrad:到目前为止,维护问题并不严重.我有一些类依赖于调用 container.Resolve<> 的容器对象.而且我不想让我的代码取决于我认为的基础设施.我仍在尝试一些东西,所以我注意到当这个项目从 ninject 切换到 Castle 时,我不得不更改很多代码.

@Blair Conrad: The maintenance issues are not severe until now. I had some classes depend on the container object calling container.Resolve<>. And I don't want to have my code depending on what I think is infrastructure. I'm still trying things out so I noticed I had to change a lot of code when switching from ninject to castle for this project.

@flowers:嗯.我喜欢你的拳头解决方案.它结合了我尝试过的两种解决方案中有效的东西.我想我仍然在对象方面考虑得太多,而在接口/职责方面考虑得还不够多.我尝试过专门建造的工厂,但我想让他们在幕后使用容器来创建对象,但我还没有找到如何以干净的方式将容器 DI 到对象中.

@flowers: Hmm. I like your fists solution. It combines the things that work from both solutions I've tried. I think I was still thinking too much in objects and not enough in interfaces/responsibilities. I tried purpose built factories but I would like to have them use the container behind the scenes to create the objects and I havn't found out how I can DI the container into objects in a clean way.

推荐答案

依赖注入的主要好处,至少在我的应用程序中,是能够编写与上下文无关的代码.从这个角度来看,您的第二个解决方案似乎真的颠覆了 DI 可能给您带来的好处.如果上帝对象"向引用它的每个类公开不同的接口,它可能不会太邪恶.但如果你走到那一步,我不明白你为什么不把它一直带到篮筐.

The main benefit of Dependency Injection, at least in my applications, is the ability to write code that is context agnostic. From that perspective, your second solution seems like it really subverts the benefit DI could be giving you. If the 'god object' exposes different interfaces to each class that references it, it might not be too evil. But if you went that far I don't see why you don't take it all the way to the hoop.

示例:您的 God 对象有一个 getFoo() 方法和一个 getBar() 方法.对象 A 需要一个 Foo,对象 B 需要一个 Bar.如果 A 只需要一个 Foo,则 Foo 应该直接注入 A 并且 A 根本不应该知道 God.但是如果 A 需要继续创建 Foos,那么将 A 引用到 God 几乎是不可避免的.但是你可以通过缩小对上帝的引用类型来保护自己免受绕过上帝所造成的伤害.如果你让 God 实现 FooFactory 并给 A 一个 God 实现的 FooFactory 的引用,你仍然可以以上下文无关的方式在 A 中编写代码.这增加了代码重用的机会,并增加了你对上帝的改变不会导致意外副作用的信心.例如,从 God 中删除 getBar() 时,您可以确定 A 类不会中断.

Example: Your God object has a getFoo() method and a getBar() method. Object A needs a Foo, object B needs a Bar. If A just needs one Foo, Foo should be injected directly into A and A should not be aware of God at all. But if A needs to keep creating Foos, giving A a reference to God is pretty much inevitable. But you can protect yourself from the damage done by passing God around by narrowing the type of the reference to God. If you make God implement FooFactory and give A a reference to the FooFactory implemented by God, you can still write the code in A in a context-neutral way. That improves the opportunities for code reuse, and it increases your confidence that a change to God will not cause unexpected side-effects. For example, you can be certain when removing getBar() from God that class A won't break.

但是......如果你无论如何都想要拥有所有这些接口,你可能最好编写专门构建的工厂类并将所有对象(包括工厂)连接在一起,在容器内,而不是包装容器根本.容器仍然可以配置工厂.

BUT ... if you're going to have all those interfaces anyway, you're probably better off writing purpose-built factory classes and wiring all your objects together, factories included, within the container, rather than wrapping the container at all. The container can still configure the factories.

这篇关于IoC,你把容器放在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆