编译时的依赖注入 [英] Dependency Injection in compile-time

查看:76
本文介绍了编译时的依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么所有的DI框架在应用程序启动之前都会在运行时检查所有依赖项?为什么不在编译时检查一下,这样做有什么好处呢?

Why all DI frameworks check for all dependency in runtime before application start? Why not to check that in compile-time, what are benefits for that?

是否可以更改已部署应用程序中的依赖关系?
例如,当应用程序启动时,它通过电子邮件发送通知,但是之后我们可以更改为通过短信发送而不停止应用程序吗?

Is it possible to change dependency in deployed application? For example when application started it sends notification through email, but after can we change to send through sms without stopping application?

推荐答案

根据定义,

DI容器通过使用反射来工作,这意味着运行时元数据。如果希望在编译时检查所有内容,则不应使用DI容器,而应手动连接依赖项。手工应用DI是称为纯DI 的常见做法。 / p>

DI Containers by definition work by using reflection which means runtime metadata. If you want everything to be checked at compile-time, you should not use a DI Container, but instead hand-wire your dependencies. Applying DI by hand is a common practice called Pure DI.


但是之后我们可以更改为通过短信发送而不停止应用程序吗?

but after can we change to send through sms without stopping application?

您似乎需要应用程序在保持运行的同时响应配置更改。有一些常见的模式可以帮助您实现这一目标。通常,您只需要一次定义该应用程序的组件对象图(包含行为及其依赖项的类链)。尽管您可能会根据请求创建此类图,但图的形状以后不应更改。而是使用诸如代理和复合的模式。例如,考虑以下接口和实现:

You seem to require the application to respond to configuration changes while keeping running. There are common patterns that allow you to achieve this. Typically you want to define that application's component object graph (the chain of classes that contain behavior with their dependencies) once. Although you might create such graph per request, the shape of the graph should not change later on. Instead, you use patterns such as proxy and composite. For instance considering the following interface and implementations:

interface INotificationSender
{
    void Send(string message);
}

class MailNotificationSender : INotificationSender { ... }

class SmsNotificationSender : INotificationSender { ... }

我们可以如下定义代理:

We can define a Proxy as follows:

class ConfigBasedNotificationSenderProxy : INotificationSender
{
    private readonly INotificationSender mail;
    private readonly INotificationSender sms;

    public ConfigBasedNotificationSenderProxy(
        INotificationSender mail, INotificationSender sms)
    {
        this.mail = mail;
        this.sms = sms;
    }

    public void Send(string message)
    {
        bool sendThroughMail = ReadFromConfgWhereToSendTo();
        var sender = sendThroughMail ? this.mail : this.sms;
        sender.Send(message);
    }
}

您可以在应用程序启动时构建以下对象图:

You can build the following object graph at application startup:

var sender = new ConfigBasedNotificationSenderProxy(
    new MailNotificationSender(...)
    new SmsNotificationSender(...));

您也可以用DI容器将其连接起来,也可以手工完成(纯DI)。但是,我要在这里重点说明的是,即使您需要更改应用程序在运行时的行为方式,也无需重新连接应用程序。您应该能够通过使用代理实现来更改应用程序对象图中的调用图。

You can wire this with a DI Container as well, or do it by hand (Pure DI). Important point however that I'm trying to make here is, that even if you need to change how the application behaves at runtime, you don't need to rewire your application. You should be able to change the call graph that goes through the application's object graphs by using Proxy implementations.

这篇关于编译时的依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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