C# 注入工具方式[Inject]

引言

使用[Inject]标签,可以根据字段类型自动注入一些数据 是非常好使用 方便调用类与类之间的成员 和 函数 避免重复获取组件 游戏开始只读取一次 就可以直到游戏关闭为止

注入方式(成功 和 注销)

新建XX类 需要挂到Hierarchy面板上 任意一个物体
举个子列先挂到Canvas 需要注入A类
代码如下:
public class XX : MonoBehaviour
{
void Awake()
{
A a = GameObject.Find(“Canvas”).GetComponent< A >();
EasyInjector.Instance.AddInject(a);
}

void OnDestroy()
{
    EasyInjector.Instance.RemoveInject<A>();
}

}

注意一点: 必须要说到 A类注入成功了 在Awake 里面函数 但是如果切换场景时, 那就必须要移除 A类注入方式 在OnDestroy()函数里面 , 如果再切回来场景时发现之前注入A类 没有被注销的话 就会导致重复注入A类成功 就会出现其他未知BUG

使用方式

由于上面已经讲了如何注入和注销,如何使用 首先必须要继承MonoInjected ,单独写一个MonoInjected
代码如下
// 可注入的Mono基类,所有子类如果复写Awake, 需要base.Awake();

public class MonoInjected : MonoBehaviour
{
protected virtual void Awake()
{
EasyInjector.ReflectionInject(this);
}
}

只允许继承它 才可以使用注入标签方式

比如你A类 需要调用B类一些成员那么 代码如下

public class A : MonoInjected
{
[Inject]
public B m_b { get; set; };

public void Start()
{
      m_b.成员或者函数;//前提是 B类成员和函数 得public 公开 否则无法调用
}

}

注入工具代码

直接上代码

public class EasyInjector
{
protected Dictionary<Type, object> m_dicInjection; // 注入的类型和实例

protected Dictionary<Type, List<InjectVO>> m_dlInjected;   // 已成功注入属性
protected Dictionary<Type, List<InjectVO>> m_dlUnjected;   // 未成功注入属性



protected static EasyInjector _instance = null;
public static EasyInjector Instance 
{ 
    get 
    {
        if (_instance == null)
        {
            _instance = new EasyInjector();
            _instance.m_dicInjection = new Dictionary<Type, object>();
            _instance.m_dlInjected = new Dictionary<Type,List<InjectVO>>();
            _instance.m_dlUnjected = new Dictionary<Type,List<InjectVO>>();
        }
        return _instance;
    } 
}

//调用 注入成功函数

public void AddInject<T>(T obj) 
{
    Type tt = typeof(T);
    if (m_dicInjection.ContainsKey(tt))
        m_dicInjection[tt] = obj;
    else
        m_dicInjection.Add(tt, obj);


    if (m_dlUnjected.ContainsKey(tt))
    {
        if (!m_dlInjected.ContainsKey(tt))
            m_dlInjected.Add(tt, new List<InjectVO>());
            
        foreach (InjectVO ij in m_dlUnjected[tt])
        {
            ij.injectPpt.SetValue(ij.injectObj, obj, null);
            m_dlInjected[tt].Add(ij);
        }

        m_dlUnjected.Remove(tt);
    }
}

public void AddInject(Type type, object obj)
{
    if (m_dicInjection.ContainsKey(type))
        m_dicInjection[type] = obj;
    else
        m_dicInjection.Add(type, obj);


    if (m_dlUnjected.ContainsKey(type))
    {
        if (!m_dlInjected.ContainsKey(type))
            m_dlInjected.Add(type, new List<InjectVO>());

        foreach (InjectVO ij in m_dlUnjected[type])
        {
            ij.injectPpt.SetValue(ij.injectObj, obj, null);
            m_dlInjected[type].Add(ij);
        }

        m_dlUnjected.Remove(type);
    }
}

// 需要注销注入 调用移除函数

public void RemoveInject<T>()
{
    Type tt = typeof(T);
    if (m_dicInjection.ContainsKey(tt))
        m_dicInjection.Remove(tt);

    if (m_dlInjected.ContainsKey(tt))
    {
        if (!m_dlUnjected.ContainsKey(tt))
            m_dlUnjected.Add(tt, new List<InjectVO>());

        foreach (InjectVO ij in m_dlInjected[tt])
        {
            ij.injectPpt.SetValue(ij.injectObj, null, null);
            m_dlUnjected[tt].Add(ij);
        }

        m_dlInjected.Remove(tt);
    }
}

public T GetInject<T>()
{
    Type tt = typeof(T);
    if (m_dicInjection.ContainsKey(tt))
        return (T)m_dicInjection[tt];

    return default(T);
}

public object GetInject(Type t)
{
    if (m_dicInjection.ContainsKey(t))
        return m_dicInjection[t];

    return null;
}



protected void Injection(object injectTarget)
{
    Type tp = injectTarget.GetType();
    MemberInfo[] members = tp.FindMembers(MemberTypes.Property,
                                                      BindingFlags.FlattenHierarchy |
                                                      BindingFlags.SetProperty |
                                                      BindingFlags.Public |
                                                      BindingFlags.Instance,
                                                      null, null);

    foreach (MemberInfo member in members)
    {
        object[] injections = member.GetCustomAttributes(typeof(Inject), true);
        if (injections.Length > 0)
        {
            //Inject attr = injections[0] as Inject;
            PropertyInfo ppt = member as PropertyInfo;
            Type pptType = ppt.PropertyType;

            var obj = EasyInjector.Instance.GetInject(pptType);
            if (obj == null)  // 尚未注入的对象
            {
                if (!m_dlUnjected.ContainsKey(pptType))
                    m_dlUnjected.Add(pptType, new List<InjectVO>());

                m_dlUnjected[pptType].Add(new InjectVO(injectTarget, ppt));
            }
            else  // 已注入的对象
            {
                if (!m_dlInjected.ContainsKey(pptType))
                    m_dlInjected.Add(pptType, new List<InjectVO>());

                m_dlInjected[pptType].Add(new InjectVO(injectTarget, ppt));

                ppt.SetValue(injectTarget, obj, null);
            }
        }
    }
}

public static void ReflectionInject(object c)
{
    EasyInjector.Instance.Injection(c);
}


public class InjectVO    
{
    public object injectObj;
    public PropertyInfo injectPpt;

    public InjectVO(object target, PropertyInfo pptInfo) 
    { 
        injectObj = target;
        injectPpt = pptInfo;
    }
}

}

// 在非Mono中使用注入,需要在类构造函数中调用 EasyInjector.ReflectionInject(this);

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false,Inherited = true)]
public class Inject : Attribute
{
public Inject() { }

public Inject(object n)
{
    name = n;
}

public object name { get; set; }

}

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值