为什么我需要一个 IoC 容器而不是简单的 DI 代码? [英] Why do I need an IoC container as opposed to straightforward DI code?

查看:23
本文介绍了为什么我需要一个 IoC 容器而不是简单的 DI 代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用 依赖注入 (DI) 一段时间,在构造函数、属性或方法.我从未觉得需要使用 控制反转 (IoC) 容器.然而,我读得越多,我就越感到来自社区的使用 IoC 容器的压力.

I've been using Dependency Injection (DI) for a while, injecting either in a constructor, property, or method. I've never felt a need to use an Inversion of Control (IoC) container. However, the more I read, the more pressure I feel from the community to use an IoC container.

我使用过 .NET 容器,例如 StructureMapNInjectUnityFunq.我仍然看不到 IoC 容器将如何使我的代码受益/改进.

I played with .NET containers like StructureMap, NInject, Unity, and Funq. I still fail to see how an IoC container is going to benefit / improve my code.

我也害怕在工作中开始使用容器,因为我的许多同事会看到他们不理解的代码.他们中的许多人可能不愿意学习新技术.

I'm also afraid to start using a container at work because many of my co-workers will see code which they don't understand. Many of them may be reluctant to learn new technology.

请说服我我需要使用 IoC 容器.我将在与工作中的开发人员同事交谈时使用这些论点.

Please, convince me that I need to use an IoC container. I'm going to use these arguments when I talk to my fellow developers at work.

推荐答案

哇,不敢相信乔尔会喜欢这个:

Wow, can't believe that Joel would favor this:

var svc = new ShippingService(new ProductLocator(), 
   new PricingService(), new InventoryService(), 
   new TrackingRepository(new ConfigProvider()), 
   new Logger(new EmailLogger(new ConfigProvider())));

在此之上:

var svc = IoC.Resolve<IShippingService>();

许多人没有意识到您的依赖链可以嵌套,并且手动连接它们很快就会变得笨拙.即使是工厂,重复代码也不值得.

Many folks don't realize that your dependencies chain can become nested, and it quickly becomes unwieldy to wire them up manually. Even with factories, the duplication of your code is just not worth it.

IoC 容器可能很复杂,是的.但是对于这个简单的案例,我已经证明它非常简单.

IoC containers can be complex, yes. But for this simple case I've shown it's incredibly easy.

好的,让我们进一步证明这一点.假设您有一些要绑定到智能 UI 的实体或模型对象.这个智能 UI(我们将其称为 Shindows Morms)希望您实现 INotifyPropertyChanged 以便它可以进行更改跟踪 &相应地更新用户界面.

Okay, let's justify this even more. Let's say you have some entities or model objects that you want to bind to a smart UI. This smart UI (we'll call it Shindows Morms) wants you to implement INotifyPropertyChanged so that it can do change tracking & update the UI accordingly.

好吧,这听起来并不难"所以你开始写作.

"OK, that doesn't sound so hard" so you start writing.

你从这个开始:

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime CustomerSince { get; set; }
    public string Status { get; set; }
}

..并以这个结束:

public class UglyCustomer : INotifyPropertyChanged
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            string oldValue = _firstName;
            _firstName = value;
            if(oldValue != value)
                OnPropertyChanged("FirstName");
        }
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            string oldValue = _lastName;
            _lastName = value;
            if(oldValue != value)
                OnPropertyChanged("LastName");
        }
    }

    private DateTime _customerSince;
    public DateTime CustomerSince
    {
        get { return _customerSince; }
        set
        {
            DateTime oldValue = _customerSince;
            _customerSince = value;
            if(oldValue != value)
                OnPropertyChanged("CustomerSince");
        }
    }

    private string _status;
    public string Status
    {
        get { return _status; }
        set
        {
            string oldValue = _status;
            _status = value;
            if(oldValue != value)
                OnPropertyChanged("Status");
        }
    }

    protected virtual void OnPropertyChanged(string property)
    {
        var propertyChanged = PropertyChanged;

        if(propertyChanged != null)
            propertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

这是令人作呕的管道代码,我认为,如果您手动编写这样的代码您就是在从客户那里窃取信息.有更好、更智能的工作方式.

That's disgusting plumbing code, and I maintain that if you're writing code like that by hand you're stealing from your client. There are better, smarter way of working.

听说过这个词,更聪明地工作,而不是更努力地工作吗?

Ever hear that term, work smarter, not harder?

想象一下,您团队中的某个聪明人走过来说:这是一种更简单的方法"

Well imagine some smart guy on your team came up and said: "Here's an easier way"

如果您使您的属性虚拟化(冷静,这没什么大不了的),那么我们可以自动编织该属性行为.(这就是所谓的AOP,不过别管它的名字,专注于它会为你做什么)

If you make your properties virtual (calm down, it's not that big of a deal) then we can weave in that property behavior automatically. (This is called AOP, but don't worry about the name, focus on what it's going to do for you)

根据您使用的 IoC 工具,您可以执行如下所示的操作:

Depending on which IoC tool you're using, you could do something that looks like this:

var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper());

噗!所有这些手动 INotifyPropertyChanged BS 现在都会在相关对象的每个虚拟属性设置器上自动为您生成.

Poof! All of that manual INotifyPropertyChanged BS is now automatically generated for you, on every virtual property setter of the object in question.

这是魔法吗?是的!如果您可以相信这段代码可以完成它的工作这一事实,那么您可以安全地跳过包装 mumbo-jumbo 的所有属性.您有业务问题需要解决.

Is this magic? YES! If you can trust the fact that this code does its job, then you can safely skip all of that property wrapping mumbo-jumbo. You've got business problems to solve.

IoC 工具在 AOP 中的一些其他有趣用途:

Some other interesting uses of an IoC tool to do AOP:

  • 声明式 &嵌套数据库事务
  • 声明式 &嵌套工作单元
  • 记录
  • 前置/后置条件(按合同设计)

这篇关于为什么我需要一个 IoC 容器而不是简单的 DI 代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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