namespace Simple.Ioc
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public class SimpleIoc
{
#region Instance
/// <summary>
/// 记录注册信息
/// </summary>
private readonly Dictionary<string, object> dictionary;
/// <summary>
/// 单例对象
/// </summary>
private static readonly SimpleIoc dataContent = new SimpleIoc();
/// <summary>
/// 单例锁
/// </summary>
private static object lockObj = new object();
/// <summary>
/// 获取简单ioc容器对象
/// </summary>
/// <returns></returns>
public static SimpleIoc Instance => dataContent;
/// <summary>
/// 创建实例
/// </summary>
private SimpleIoc() => dictionary = new Dictionary<string, object>();
#endregion
#region Assembly
/// <summary>
/// 获取指定路径dll中的实例对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="dllPath">dll相对路径</param>
/// <param name="parameters">实例参数</param>
/// <returns>实例对象</returns>
public T GetObject<T>(string dllPath, params object[] parameters)
{
var assembly = ExistedAssembly(dllPath);
var type = GetType<T>(assembly).First();
var result = Activator.CreateInstance(type, parameters);
return (T)result;
}
/// <summary>
/// 获取指定路径dll中的实例对象数组
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="dllPath">dll相对路径</param>
/// <param name="parameters">实例参数</param>
/// <returns>实例对象数组</returns>
public IEnumerable<T> GetObjectArray<T>(string dllPath, params object[] parameters)
{
var assembly = ExistedAssembly(dllPath);
var types = GetType<T>(assembly);
foreach (var type in types)
{
var result = Activator.CreateInstance(type, parameters);
yield return (T)result;
}
}
/// <summary>
/// 检查传入的程序集是否被加载
/// </summary>
/// <param name="dllPath">程序集相对路径</param>
/// <param name="excuteLoad">true没有被加载,执行加载程序操作,false没有被加载,不加载程序集</param>
/// <returns>返回被加载的程序集对象,返回null传入的程序集没有被加载</returns>
public Assembly ExistedAssembly(string dllPath, bool excuteLoad = true)
{
var fileType = ".dll";
var dllName = dllPath;
if (dllPath.EndsWith(fileType.ToUpper()))
{
dllName = dllPath.Replace(fileType.ToUpper(), string.Empty);
}
else if (dllPath.EndsWith(fileType))
{
dllName = dllPath.Replace(fileType, string.Empty);
}
var existedItem = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(i => i.GetName().Name == dllName);
if (existedItem == null && excuteLoad)
{
var dllFullPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dllName + ".dll");
existedItem = Assembly.LoadFrom(dllFullPath);
}
return existedItem;
}
/// <summary>
/// 从传入的程序集中获取指定的类型
/// </summary>
/// <typeparam name="T">要获取的类型</typeparam>
/// <param name="assembly">程序集对象</param>
/// <returns>当前满足条件的类型</returns>
public IEnumerable<Type> GetType<T>(Assembly assembly)
{
Type itype0 = typeof(T);
Type itype1;
Type[] types = assembly.GetTypes();
foreach (var type in types)
{
itype1 = type.GetInterface(typeof(T).FullName);
if (itype1 == null) continue;
if (itype1.FullName == itype0.FullName)
{
yield return type;
}
}
}
#endregion
#region Register
/// <summary>
/// 注册对象信息
/// </summary>
/// <param name="name">实例对象检索名称</param>
/// <param name="obj">实例对象</param>
/// <returns>实例对象</returns>
public SimpleIoc SetData(string name, object obj)
{
lock (lockObj)
{
dictionary.Add(name, obj);
}
return this;
}
/// <summary>
/// 注册对象信息
/// </summary>
/// <param name="obj">实例对象</param>
/// <returns></returns>
public SimpleIoc SetData(object obj) => SetData(obj.GetType().FullName, obj);
/// <summary>
/// 注册dll信息
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <param name="dllName">dll相对目录</param>
/// <returns></returns>
public SimpleIoc SetData<T>(string dllName) => SetData(typeof(T).FullName, dllName);
#endregion
#region GetInstance
/// <summary>
/// 获取已注册的实例对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="name">实例对象检索名称</param>
/// <returns>实例对象</returns>
public T GetData<T>(string name)
{
lock (lockObj)
{
if (dictionary.ContainsKey(name))
{
return (T)dictionary[name];
}
}
return default(T);
}
/// <summary>
/// 获取已注册的实例对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <returns>实例对象</returns>
public T GetData<T>()
{
var result = GetData<T>(typeof(T).FullName);
if (result == null)
{
List<object> list = new List<object>();
lock (lockObj)
{
list.AddRange(dictionary.Values);
}
var temp = list.Find(i => i is T);
if (temp != null)
{
result = (T)temp;
}
}
return result;
}
/// <summary>
/// 获取已注册的实例对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="parameters">对象实例参数</param>
/// <returns>实例对象</returns>
public T GetInstance<T>(params object[] parameters) => GetObject<T>(GetData<string>(typeof(T).FullName), parameters);
#endregion
}
}
简单ioc容器实现,可作为插件框架的核心逻辑,个人文档记录
最新推荐文章于 2022-10-10 08:23:28 发布