Unity3D C# IOCContainer-DI/IOC容器-依赖关系解耦处理

一、为什么需要IOC容器

IOC容器在大学学习中应该会经常见到,比如Java中大名鼎鼎的Spring架构,还有C#中的Autofac。

IOC容器可以帮助我们解耦对象之间的依赖关系,让对象只需关注自己的业务逻辑,而不需要关心如何创建和维护其他对象。

我这么说可能太过于高大上,我们举一个浅显的例子

假设我们有一个餐厅管理系统,它由三个类组成:
1.餐厅类(Restaurant),
2.厨师类(Chef)
3.服务员类(Waiter)。

餐厅类需要一个厨师类和一个服务员类来运行,也就是说餐厅类依赖于这两个类,有时可能需要更换。我们可以使用IOC容器来管理这些依赖关系。

二、IOC容器达到的效果

我们首先还原上文的情景,实现这些类,其中最难处理的便是餐厅类了,对厨师和服务员都有依赖,我们首先实现独立的两个类

public interface IChef{
    
    void Cook();}
public interface IWaiter{
    
    void Serve();}

class Chef : IChef
{
    
    
    public void Cook() {
    
     /* code to cook the food */ }
}

class Waiter : IWaiter
{
    
    
    public void Serve() {
    
     /* code to serve the food */ }
}

接下来处理餐厅类,因为餐厅类依赖于服务员,依赖于厨师,但是难免要更换厨师和服务员。
我们不用关注IOC容器的实现方式,只需要看这张图

需要厨师时我们拿到IChef接口,不关心具体实现的类型
需要服务员拿IWaiter接口,不关心实现类型

在这里插入图片描述
也就是说,我们餐厅对于服务员和厨师,只关心他们能否做饭(IChef)和服务(IWaiter),而不是他们其他的内容。
而IOCContainer就是负责绑定具体和抽象的一个媒介。这里不要纠结IOCContainer的实现,后文将给出具体实现。

class Restaurant
{
    
    
	//这里定义一个容器,存储依赖关系
    private IOContainer _container;
    public Restaurant(IOContainer container)
    {
    
    
        _container = container;
        //把接口和类型绑定依赖关系
        _container.Register<IChef, Chef>();
        _container.Register<IWaiter, Waiter>();
    }

    public void Serve()
    {
    
    
    	//解析依赖关系
        var chef = _container.Reslove<IChef>();
        var waiter = _container.Reslove<IWaiter>();
        chef.Cook();
        waiter.Serve();
    }
}

class Program
{
    
    
    static void Main(string[] args)
    {
    
    
    	//建立IOC容器
        var container = new IOContainer();
        //餐厅对象
        var restaurant = new Restaurant(container);
        //调用方法
        restaurant.Serve();
    }
}

三、简易IOC容器实现

正如你所见,IOC容器唯一的作用就是绑定抽象和具体,实现控制反转,不需要多么花里胡哨,大道至简。

在代码中,笔者将给出详细的注释。

public class IOContainer
    {
    
    
    	//首先实现依赖关系存储,Key为接口类型,object为实例
        private Dictionary<Type, object> container = new Dictionary<Type, object>();
		
		
        public void Register<T,K>()   where K : class, T 
        {
    
    
            Register<T>(Activator.CreateInstance<K>());
        }
		//绑定依赖
        public void Register<T>(T instance) 
        {
    
    
            Type key = typeof(T);
            if (container.ContainsKey(key))
            {
    
    
                container[key] = instance;
            }
            else
            {
    
    
                container.Add(key, instance);
            }
        }
		//解析依赖
        public T Reslove<T>() where T : class
        {
    
    
            if (container.ContainsKey(typeof(T)))
            {
    
    
                return container[typeof(T)] as T;
            }
            throw new NullReferenceException("No such type in this IOCContainer!");
        }


    }

如果对你有帮助,可以点一个免费的赞或者关注笔者,在Github上为yueh0607的项目点一个star(三克油)

猜你喜欢

转载自blog.csdn.net/qq_46273241/article/details/128756319
今日推荐