Can anyone explain to me, at length, how to use IOC containers?

后端 未结 7 1725
执笔经年
执笔经年 2021-02-05 15:47

I use dependency injection through parameters and constructors extensively. I understand the principle to this degree and am happy with it. On my large projects, I end up with t

相关标签:
7条回答
  • 2021-02-05 16:27

    Try these:

    • http://www.martinfowler.com/articles/injection.html
    • http://msdn.microsoft.com/en-us/library/aa973811.aspx
    0 讨论(0)
  • 2021-02-05 16:31

    In the past few weeks, I've taken the plunge from dependency-injection only to full-on inversion of control with Castle, so I understand where your question is coming from.

    Some reasons why I wouldn't want to use an IOC container:

    1. It's a small project that isn't going to grow that much. If there's a 1:1 relationship between constructors and calls to those constructors, using an IOC container isn't going to reduce the amount of code I have to write. You're not violating "don't repeat yourself" until you're finding yourself copying and pasting the exact same "var myObject = new MyClass(someInjectedDependency)" for a second time.

    2. I may have to adapt existing code to facilitate being loaded into IOC containers. This probably isn't necessary until you get into some of the cooler Aspect-oriented programming features, but if you've forgotten to make a method virtual, sealed off that method's class, and it doesn't implement an interface, and you're uncomfortable making those changes because of existing dependencies, then making the switch isn't quite as appealing.

    3. It adds an additional external dependency to my project -- and to my team. I can convince the rest of my team that structuring their code to allow DI is swell, but I'm currently the only one that knows how to work with Castle. On smaller, less complicated projects, this isn't going to be an issue. For the larger projects (that, ironically, would reap the most benefit from IOC containers), if I can't evangelize using an IOC container well enough, going maverick on my team isn't going to help anybody.

    Some of the reasons why I wouldn't want to go back to plain DI:

    1. I can add or take away logging to any number of my classes, without adding any sort of trace or logging statement. Having the ability for my classes to become interwoven with additional functionality without changing those classes, is extremely powerful. For example:

      Logging: http://ayende.com/Blog/archive/2008/07/31/Logging--the-AOP-way.aspx

      Transactions: http://www.codeproject.com/KB/architecture/introducingcastle.aspx (skip down to the Transaction section)

    2. Castle, at least, is so helpful when wiring up classes to dependencies, that it would be painful to go back.

    For example, missing a dependency with Castle:

    "Can't create component 'MyClass' as it has dependencies to be satisfied. Service is waiting for the following dependencies:

    Services: - IMyService which was not registered."

    Missing a dependency without Castle:

    Object reference is not set to an instance of an object

    Dead Last: The ability to swap injected services at runtime, by editing an Xml File. My perception is that this is the most tauted feature, but I see it as merely icing on the cake. I'd rather wire up all my services in code, but I'm sure I'll run into a headache in the future where my mind will be changed on this.

    I will admit that -- being a newbie to IOC and Castle -- I'm probably only scratching the surface, but so far, I genuinely like what I see. I feel like the last few projects I've built with it are genuinely capable of reacting to the unpredictable changes that arise from day to day at my company, a feeling I've never quite had before.

    0 讨论(0)
  • 2021-02-05 16:34

    If you have over a hundred of classes implementing a common interface, an IoC won't help very much, you need a factory. That way, you may do the following:

    public interface IMyInterface{
        //...
    }
    
    public class Factory{
    
        public static IMyInterface GetObject(string param){
            // param is a parameter that will help the Factory decide what object to return
            // (that is only an example, there may not be any parameter at all)
        }
    }
    
    //...
    // You do not depend on a particular implementation here
    IMyInterface obj = Factory.GetObject("some param");
    

    Inside the factory, you may use an IoC Container to retrieve the objects if you like, but you'll have to register each one of the classes that implement the given interface and associate them to some keys (and use those keys as parameters in GetObject() method).

    An IoC is particularly useful when you have to retrieve objects that implement different interfaces:

    IMyInteface myObject = Container.GetObject<IMyInterface>();
    IMyOtherInterface myOtherObject Container.GetObject<IMyOtherInterface>();
    ISomeOtherInterface someOtherObject = Container.GetObject<ISomeOtherInterface>();
    

    See? Only one object to get several different type objects and no keys (the intefaces themselves are the keys). If you need an object to get several different object, but all implementing the same interface, an IoC won't help you very much.

    0 讨论(0)
  • 2021-02-05 16:37

    I have no links but can provide you with an example:

    You have a web controller that needs to call a service which has a data access layer.

    Now, I take it in your code you are constructing these objects your self at compile time. You are using a decent design pattern, but if you ever need to change the implementation of say the dao, you have to go into you code and remove the code that sets this dependency up, recompile / test/ deploy. But if you were to use a IOC container you would just change the class in the configuration and restart the application.

    0 讨论(0)
  • 2021-02-05 16:42

    IoC containers usually do the dependency injections which in some projects are not a big deal , but some of the frameworks that provide IoC containers offer other services that make it worth to use them. Castle for example has a complete list of services besides an IoC container.Dynamic proxies ,Transaction management and NHibernate facilities are some of them. Then I think you should consider IoC contianers as a part of an application framework.

    Here's why I use an IoC container: 1.Writing unit tests will be easier .Actually you write different configurations to do different things 2.Adding different plugins for different scenarios(for different customers for example) 3.Intercepting classes to add different aspects to our code. 4.Since we are using NHibernate ,Transaction management and NHibernate facilites of Castle are very helpful in developing and maintaining our code . It's like every technical aspects of our application is handled using an application framework and we have time to think about what customers really want.

    0 讨论(0)
  • 2021-02-05 16:44

    Jeremy Frey misses one of the biggest reasons for using an IOC container: it makes your code easier to mock and test.

    Encouraging the use of interfaces has lots of other nice benefits: better layering, easier to dynamically generate proxies for things like declarative transactions, aspect-oriented programming and remoting.

    If you think IOC is only good for replacing calls to "new", you don't get it.

    0 讨论(0)
提交回复
热议问题