c#使用IOC容器替代单例

单例缺点

可以参考这篇文章:https://blog.csdn.net/zhujiangtaotaise/article/details/110443138
总结就是单例对 OOP 特性的支持不友好,对代码的扩展性不友好,不支持有参数的构造函数,会一直占着生命周期。

IOC容器

  1. 创建一个Service的父类:
//Service的父类
public class SystemService : IDisposable,ISetUp
{
    public virtual void Setup()
    {
        
    }

    public virtual void Dispose()
    {
    }
}

这个Service的父类实现了两个接口,功能分别时初始化时,和这个类销毁时做的事情。

public interface ISetUp
{
    void Setup();
}
  1. 创建一个容器类,用字典存储Service
using System;
using System.Collections.Generic;

namespace Platform
{
    //容器类
    public class ServiceContainer
    {
        private Dictionary<Type, IDisposable> systemServices = new();
        public T AddService<T>() where T : IDisposable, ISetUp, new()
        {
            Type key = typeof (T);
            if (systemServices.ContainsKey(key))
                return (T) systemServices[key];
            T obj = new T();
            obj.Setup();
            systemServices.Add(key, obj);
            return obj;
        }
        
        public void RemoveService<T>()
        {
            var type = typeof(T);
            if (systemServices.TryGetValue(type, out IDisposable systemService))
            {
                systemServices.Remove(type);
                systemService.Dispose();
            }
        }
        
        public T GetService<T>() where T : IDisposable
        {
            var type = typeof(T);
            if (systemServices.TryGetValue(type, out IDisposable systemService))
            {
                return (T)systemService;
            }
            throw new Exception("Service Uninitialized");
        }
        
        public T AddService<T, B>(B para1) where T : IDisposable, ISetUp<B>, new()
        {
            var type = typeof(T);

            if (systemServices.ContainsKey(type))
            {
                return (T)systemServices[type];
            }

            T t = new T();
            t.Setup(para1);
            systemServices.Add(type, t);

            return t;
        }

        public T AddService<T, B, C>(B para1, C para2) where T : IDisposable,ISetUp<B,C>, new()
        {
            var type = typeof(T);

            if (systemServices.ContainsKey(type))
            {
                return (T)systemServices[type];
            }

            T t = new T();
            t.Setup(para1, para2);
            systemServices.Add(type, t);
            return t;
        }
    }
}

其主要方法就是首次通过AddService的方法得到Service,然后后续通过GetService得到Service,如果要销毁Service,则调用RemoveService。

这里为了扩展能传多个参数进来,因为多定义了几个泛型的IsetUp方法:

public interface ISetUp<A>
{
    void Setup(A a);
}

public interface ISetUp<A, B>
{
    void Setup(A a, B b);
}

  1. 对外使用的API
using System;

namespace Platform
{
    //对外提供使用的类
    //对单例的改进:可以传参进去,可以解除这个类
    public static class World
    {
        public static ServiceContainer System = new();

        public static T AddService<T>() where T : SystemService,new()
        {
            return System.AddService<T>();
        }
        
        public static T AddService<T, B>(B para1) where T : IDisposable, ISetUp<B>, new()
        {
            return System.AddService<T, B>(para1);
        }

        public static T AddService<T, B, C>(B para1, C para2) where T : IDisposable, ISetUp<B, C>, new()
        {
            return System.AddService<T, B, C>(para1, para2);
        }
        
        public static void RemoveService<T>()
        {
            System.RemoveService<T>();
        }

        public static T GetService<T>() where T : IDisposable, new()
        {
            return System.GetService<T>();
        }

    }
}

使用

     FirstService firstService = World.System.AddService<FirstService>();
       World.System.GetService<FirstService>();
       World.System.RemoveService<FirstService>();
       
       World.System.AddService<SecondService,string>("game");
       World.System.GetService<SecondService>();

Service类需要传递一个参数,两个参数都可以。不用的时候也可以解注册。

using System;

public class FirstService : SystemService
{
    
}


public class SecondService : IDisposable, ISetUp<String>
{
    public void Dispose()
    {
        
    }

    public void Update()
    {
    }

    public void Setup(string a)
    {
    }
}

猜你喜欢

转载自blog.csdn.net/KindSuper_liu/article/details/127416031