What is IOC? Need some practical code examples to

2019-02-08 08:36发布

Can someone guide me to some basic tutorials on IOC? (preferably .net/c#).

I need some hands on code to wrap my head around it :)

Is IOC similiar to DDD? or test-driven-design?

7条回答
淡お忘
2楼-- · 2019-02-08 09:09

Inversion of Control is the abstraction of logic's structure. One approach (often used synonymously with IoC) is Dependency Injection, which abstracts references between objects. When objects are freed from an application's implementation details, such as which class implements which service, they are free to focus on their core functions.

For example, let's say you have a class that needs to map Foo objects to Bar objects. You might write this:

public class FooMapper
{
    public Bar Map(Foo foo)
    {
        // ...
    }
}

and use it like this:

public class NeedsToMapFoos
{
    public void MapSomeFoos()
    {
        var fooMapper = new FooMapper();

        // ...
    }
}

While valid, this is also rigid. NeedsToMapFoos only cares that mapping occurs, not that it occurs in any specific way.

We can represent the concept of "operation sans implementation" with an interface:

public interface IFooMapper
{
    Bar Map(Foo foo);
}

and declare a dependency on that operation:

public class NeedsToMapFoos
{
    private readonly IFooMapper _fooMapper;

    public NeedsToMapFoos(IFooMapper fooMapper)
    {
        _fooMapper = fooMapper;
    }

    public void MapSomeFoos()
    {
        // ...use _fooMapper...
    }
}

Now NeedsToMapFoos has less knowledge, which means it is less complex. Instead of performing administrative duties, it is free to focus on the business case.

Well-factored objects like this are also more adaptable. Just as diamonds are rigid and clay is malleable, internal structure determines response to change.

Finally, logic written in this style is also flexible. Let's say FooMapper.Map is an expensive operation and should be cached. You can use the decorator pattern to wrap the existing implementation and seamlessly pass it to NeedsToMapFoos:

public class CachingFooMapper : IFooMapper
{
    private readonly IFooMapper _innerMapper;
    private readonly IDictionary<Foo, Bar> _cache;

    public CachingFooMapper(IFooMapper innerMapper)
    {
        _innerMapper = innerMapper;
    }

    public Bar Map(Foo foo)
    {
        // Read bar from _cache. If not there, read from inner mapper and add to _cache.
    }
}

// Usage

new NeedsToMapFoos(new CachingFooMapper(new FooMapper()));
查看更多
登录 后发表回答