在依赖注入中声明 Facade 类 [英] Declaring Facade Class in Dependency Injection

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

问题描述

我正在使用依赖注入.假设我有一个像这样的 OrderService 类:

I am using Dependency Injection. Say that I has an OrderService class like this:

public class OrderService{
    public OrderService(
        IOrderValidator validator
        , IOrderRepository repository
        , IOrderNotificator notificator){
        //assign global fields
    }

    public void SubmitOrder(Order ord){
        if(validator.IsOrderValid(ord)){
            repository.InsertNew(ord);
            notificator.Notify(ord);
        }
    }
}

现在我想创建一个外观类,例如 TypeAOrderService,由 OrderService 继承,在构造函数中声明组件,例如:

Now I wonder to create a facade class for example TypeAOrderService, as inherited by OrderService, with components declared in constructor such as:

public class TypeAOrderService : OrderService{
    public TypeAOrderService() : base(
        new OrderValidator(),
        new OrderRepository(),
        new OrderNotificator()) { }
}

(注意注入组件复杂性的实现在这里并不重要,一个适配器模式也可以代替继承).

(Note that the implementation with injected component complexity is not important here, an adapter pattern also acceptable to replace inheritance though).

这里可能有缺点,因为我们没有在组合根定义依赖项.但是我想知道在某些情况下是否可以接受.尤其是在framework component中,通过访问DI容器来使用框架并自己解决它是相当奇怪的.

There may be downsides here because we don't define the dependency at composition root. However I wonder whether it is acceptable in some situation. Especially at framework component when it is rather weird to use the framework by accessing the DI Container and resolve it yourself.

更新:

正如评论中提到的,目前我不使用任何 IOC 容器.我的观点是,在框架中使用 IOC 容器很奇怪,因为这意味着每个使用框架的应用程序都需要使用 IOC 容器.如果我的观点是错误的,请随时纠正我.

As mentioned in comment, currently I don't use any IOC container. My perspective is, it is weird to use IOC container in Framework, since it will means that every application uses the framework will need to use IOC container. If my perspective is wrong, feel free to correct me.

我所指的框架示例是例如 System.Windows.Forms.Form,其中我不使用任何 IOC 容器并且不确定依赖项.

What I am refering as the framework example is such as System.Windows.Forms.Form where I don't use any IOC container and don't determine the dependency.

推荐答案

关于是否使用IoC,我认为在框架库中使用IoC是可以的.这只是意味着您的框架有自己的容器和组合根,它们对任何消费者都完全隐藏.您可以创建使其易于使用的 Facade 类.像这样:

Regarding whether to use IoC, I think it's fine to use IoC within a framework library. It just means your framework has its own Container and Composition Root that are entirely hidden from any of its consumers. You can create Facade classes that make it easy to consume. Something like this:

public class OrderServiceFacade
{
    private readonly IOrderService OrderService;

    public class OrderServiceFacade()
    {
        this.OrderService = ContainerWrapper.Container.Resolve<IOrderService>();
    }

    public void SubmitOrder(Order ord) {
        OrderService.SubmitOrder(ord);
    }
}

ContainerWrapper 是你的 Composition Root,它是 DI Container 的包装器.

Where ContainerWrapper is your Composition Root, a wrapper around the DI Container.

internal class ContainerWrapper
{
    private Container _Container;
    public Container Container
    {
        if(_Container == null)
        {
            //initialize it
        }
        return _Container;
    }
}

当然,您需要 OrderService 和 TypeAOrderService 从新的 IOrderService 接口继承.这也将 TypeAOrderService 与 OrderService 分离,因为它可以在其构造函数中使用接口,而不是直接实例化特定的实现.如果您确实需要 TypeAOrderService 来调用 OrderService 上的方法,您可以使用装饰器模式并让 TypeAOrderService 将 IOrderService 作为附加依赖项.

Of course you would need OrderService and TypeAOrderService to inherit from a new IOrderService interface. This also decouples your TypeAOrderService from your OrderService, as it can then take interfaces in its constructor rather than directly instantiate particular implementations. In the event you actually need TypeAOrderService to call methods on OrderService, you can use the Decorator Pattern and have TypeAOrderService take IOrderService as an additional dependency.

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

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