简体   繁体   English

没有服务定位器的IOC

[英]IOC without Service Locator

Suppose I have 3 classes, Program , A (with dependencies D1 and D2 ) and B (with dependencies D3 and D4 ). 假设我有3个类, ProgramA (具有依赖项D1D2 )和B (具有依赖项D3D4 )。 Program initialises an IOC container and registers a bunch of types before creating an instance of A . Program在创建A实例之前初始化IOC容器并注册一堆类型。

class Program
{
    static void Main(string[] args)
    {
        IOC ioc = new IOC();
        //register types

        A a = ioc.Resolve<A>();
    }
}

At some point later on, a needs to create an instance of B , injecting its two dependencies into the constructor. 稍后, a需要创建一个B实例,将其两个依赖项注入到构造函数中。

Question: How should a resolve the dependencies of B ? 问:应该怎样a解决的依赖性B I have been led to believe that passing the IOC container around ie injecting it into A is the Service Locator pattern, which is bad. 我一直被认为相信,将IOC容器传递到周围(即,将其注入A是Service Locator模式,这很糟糕。 If B created C with its dependencies, B would also need to have the container injected, and the container would be littered throughout my code. 如果B使用其依赖关系创建了C ,则B也需要注入容器,并且该容器会在我的整个代码中乱扔垃圾。 This sounds like a testing nightmare. 这听起来像一场噩梦。 Using a global static doesn't sound much better. 使用全局静态听起来并不好。

It's actually simple. 实际上很简单。 If A needs B , it should accept B as constructor argument: 如果A需要B ,则应接受B作为构造函数参数:

public class A
{
    private readonly D1 d1;
    private readonly D2 d2;
    private readonly B b;

    public A(D1 d1, D2 d2, B b) {
        this.d1 = d1;
        this.d2 = d2;
        this.b = b;
    }
}

public class B
{
    private readonly D3 d3;
    private readonly D4 d4;
    private readonly C c;

    public B(D3 d3, D4 d4, C c) {
        this.d3 = d3;
        this.d4 = d4;
        this.c = c;
    }
}

This way you build up object graphs recursively and you can get very deep object graphs, which is completely fine. 这样,您就可以递归地建立对象图,并且可以获得非常深的对象图,这完全可以。 This way you only need the container in the startup path of your application (aka the Composition Root). 这样,您只需在应用程序的启动路径(也称为“合成根目录”)中使用容器。

Whether or not A needs B 'later on', or just sometimes, or hardly ever is irrelevant. A是否需要“以后”使用B ,或者只是有时候,或者几乎不需要。 Building object graphs should be fast and whether or not B is created needlessly should therefore not be an issue. 建立对象图应该很快,因此是否不必要创建B不会成为问题。

Ideally you should never inject container to your classes just to resolve the the dependencies. 理想情况下,永远不要仅将容器注入类中以解决依赖关系。 Rather you register instances in in separate place probably your startup class where in runtime application should be able to resolve dependencies automatically from the registered instances with container. 而是将实例注册在单独的位置,可能是您的启动类,在运行时应用程序中,启动类应该能够从容器中的已注册实例自动解析依赖项。

look at following example how an IOC container typically register its instances 看下面的示例IOC容器通常如何注册其实例

Register 寄存器

SimpleIoc.Default.Register< IDataService, DataService >(); SimpleIoc.Default.Register <IDataService,DataService>(); SimpleIoc.Default.Register< MainViewModel >(); SimpleIoc.Default.Register <MainViewModel>();
SimpleIoc.Default.Register< SecondViewModel >(); SimpleIoc.Default.Register <SecondViewModel>();

Resolve 解决

SimpleIoc.Default.GetInstance< MainViewModel >(); SimpleIoc.Default.GetInstance <MainViewModel>();

At some point later on, A needs to create an instance of 'B', injecting its two dependencies into the constructor. 稍后, A需要创建一个'B'实例,并将其两个依赖项注入到构造函数中。

In this case, A must take a dependency on a BFactory that can create the B 's for it. 在这种情况下, A必须依赖可以为其创建BBFactory

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 理论:“服务定位器”“ IOC容器”“ IOC”“ DI” - theory: “Service Locator” “IOC Container” “IOC” “DI” 如何在没有全局静态服务(非服务定位器解决方案)的情况下实现IOC? - how to implement IOC without a global static service (non-service locator solution)? 定制服务定位器,带有来自galasoft的MEF和IOC容器 - Custom Service Locator with MEF and IOC container from galasoft 没有服务定位器的工厂模式 - Factory pattern without service locator 没有服务定位器的CQRS调度程序 - CQRS Dispatcher Without Service Locator 没有服务定位器的域事件 - Domain Events without Service Locator IoC设计-从服务内部引用服务定位器以实现动态委托服务 - IoC Design - reference service locator from within service for dynamic delegate service 使用 IoC 容器作为某些服务的服务定位器以获得机会创建子范围 - Use IoC-container as service locator to some service to get oppotunity create sub scope 没有服务定位器的多实例的依赖注入 - Dependency injection for multiple instance without service locator 在不使用.svc和.config的情况下使用LightInject(IoC)服务 - Using LightInject (IoC) service without .svc and .config
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM