对具有许多依赖关系的类使用依赖注入框架 [英] Using Dependency Injection frameworks for classes with many dependencies

查看:145
本文介绍了对具有许多依赖关系的类使用依赖注入框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在看.NET的各种依赖注入框架,因为我觉得我正在开展的项目将从中受益匪浅。虽然我认为我很好地掌握了这些框架的功能,但我仍然不太清楚如何将它们引入大型系统。大多数演示(可理解)往往是具有一个或两个依赖关系的相当简单的类。

I have been looking at various dependency injection frameworks for .NET as I feel the project I am working on would greatly benefit from it. While I think I have a good grasp of the capabilities of these frameworks, I am still a little unclear on how best to introduce them into a large system. Most demos (understandably) tend to be of quite simple classes that have one or two dependencies.

我有三个问题...

首先,你如何处理与那些常见但不感兴趣的依赖关系,例如ILog,IApplicationSettings,IPermissions,IAudit。每个类似乎都有过度的把它们作为构造函数的参数。使用DI容器的静态实例可以在需要时使用这些实例吗?

First, how do you deal with those common but uninteresting dependencies, e.g. ILog, IApplicationSettings, IPermissions, IAudit. It seems overkill for every class to have these as parameters in their constructor. Would it be better to use a static instance of the DI container to get these when they are needed?

MyClass(ILog log, IAudit audit, IPermissions permissions, IApplicationSettings settings)
// ... versus ...
ILog log = DIContainer.Get<ILog>();

第二个,你如何处理依赖关系,使用,但可能是昂贵的创建。示例 - 类可能具有对ICDBurner接口的依赖性,但不希望创建具体实现,除非实际使用CD刻录功能。您是否在构造函数中传递到工厂(例如ICDBurnerFactory)的接口,还是再以静态的方式直接进入DI容器,并在需要的时候要求它?

Second, how do you approach dependencies that might be used, but may be expensive to create. Example - a class might have a dependency on an ICDBurner interface but not want the concrete implementation to be created unless the CD Burning feature was actually used. Do you pass in interfaces to factories (e.g. ICDBurnerFactory) in the constructor, or do you again go with some static way of getting directly to the DI Container and ask for it at the point it is needed?

第三个,假设您有一个大型Windows窗体应用程序,其中顶级GUI组件(例如MainForm)可能是数百个子面板或模态窗体的父级,每个可能有几个依赖关系。这是否意味着MainForm应该设置为具有依赖关系的子集的所有依赖项的超集?如果你这样做,那么这不会造成一个巨大的自我膨胀的怪物,构建每一个类,它可能需要你创建MainForm的时刻,浪费时间和记忆的过程?

Third, suppose you have a large Windows Forms application, in which the top level GUI component (e.g. MainForm) is the parent of potentially hundreds of sub-panels or modal forms, each of which may have several dependencies. Does this mean that MainForm should be set up to have as dependencies the superset of all the dependencies of its children? And if you did so, wouldn't this end up creating a huge self-inflating monster that constructs every single class it could ever need the moment you create MainForm, wasting time and memory in the process?

推荐答案

首先:根据需要将简单的依赖项添加到构造函数中。没有必要为每个构造函数添加每个类型,只需添加所需的。需要另外一个,只是扩展构造函数。性能不应该是一件大事,因为这些类型中的大多数可能是第一次调用后已经创建的单例。不要使用静态DI容器来创建其他对象。而是将DI容器添加到自身中,以便它可以将其自身解析为依赖关系。所以这样的东西(假设现在是Unity)

First: Add the simple dependencies to your constructor as needed. There is no need to add every type to every constructor, just add the ones you need. Need another one, just expand the constructor. Performance should not be a big thing as most of these types are likely to be singletons so already created after the first call. Do not use a static DI Container to create other objects. Instead add the DI Container to itself so it can resolve itself as a dependency. So something like this (assuming Unity for the moment)

IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);

这样,您只需在IUnityContainer上添加依赖关系,并使用它来创建昂贵或很少需要的对象。主要的优点是,当单元测试没有静态依赖性时,它容易得多。

This way you can just add a dependency on IUnityContainer and use that to create expensive or seldom needed objects. The main advantage is that it is much easier when unit testing as there are no static dependencies.

第二:不需要通过工厂类。使用上述技术,您可以使用DI容器本身在需要时创建昂贵的对象。

Second: No need to pass in a factory class. Using the technique above you can use the DI container itself to create expensive objects when needed.

三:添加DI容器和轻单依赖于主窗体,并根据需要通过DI容器创建其余部分。更多代码,但正如您所说,如果您在启动时创建所有内容,主机的启动成本和内存消耗将会通过屋顶。

Three: Add the DI container and the light singleton dependencies to the main form and create the rest through the DI container as needed. Takes a little more code but as you said the startup cost and memory consumption of the mainform would go through the roof if you create everything at startup time.

这篇关于对具有许多依赖关系的类使用依赖注入框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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