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

查看:117
本文介绍了为什么需要一个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容器,如 StructureMap Ninject Unity Funq 。我仍然看不到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.

我也害怕在工作中开始使用一个容器,因为我的许多co工作者会看到他们不明白的代码。许多人可能不愿意学习新技术。

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.

推荐答案

哇,不能相信Joel会赞成:

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(我们称之为Windows窗体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());

Poof!所有手册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:


  • 声明式和嵌套数据库事务

  • 声明式和嵌套工作单位

  • 记录

  • 前/后条件(按合同设计)

  • Declarative & nested database transactions
  • Declarative & nested Unit of work
  • Logging
  • Pre/Post conditions (Design by Contract)

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

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