.NET之IOC控制反转运用
当前场景:
如果有不同的用户。使用同一个系统。而不同的客户有某些不同的需求。在不改变系统主体的情况下,可以直接使用IOC控制反转依赖搭建项目
1.添加接口层
目前里面只有一个会员的类。里面有一个登录接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IService { public interface IUser { void Login(); } }
2.添加相应的实现层;
标准版实现层
using IService; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Service.Standard { public class User : IUser { public void Login() { Console.Write("标准版登录"); } } }
定制版实现层
using IService; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Service.Customization { public class User : IUser { public void Login() { Console.Write("定制版的登录"); } } }
3.相应的接口层和实现层都已经完善之后。开始最核心的代码;反转
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace IOCConfig { public class Convert { /// <summary> /// 返回实现类的key名 /// </summary> /// <param name="assembly"></param> /// <param name="key"></param> /// <returns></returns> private static string GetImpementClassKey(Assembly assembly, string key) { var allTypes = assembly.GetTypes(); var type = allTypes.FirstOrDefault(t => t.GetInterface(key) != null); if (type == null) { throw new NotImplementedException("未实现" + key); } return type.FullName; } /// <summary> /// 创建对象实例 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="fullName">命名空间.类型名</param> /// <param name="assemblyName">程序集</param> /// <returns></returns> public static T CreateInstance<T>(string fullName, string assemblyName) { string path = fullName + "," + assemblyName;//命名空间.类型名,程序集 Type o = Type.GetType(path);//加载类型 object obj = Activator.CreateInstance(o, true);//根据类型创建实例 return (T)obj;//类型转换并返回 } /// <summary> /// IOC控制 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="userId">客户ID</param> /// <returns></returns> public static T IocConvert<T>(int userId = 0) where T : class { string assemblyName = string.Empty ;//程序集名称 if (userId==0) { assemblyName = "Service.Standard";//标准版 } else { //可以根据不同的客户进行不同的实现层 assemblyName = "Service.Customization";//定制版 } var baseType = typeof(T).FullName; string key = GetImpementClassKey(Assembly.Load(assemblyName), baseType); return CreateInstance<T>(key, assemblyName); } } }
4.稳定前端代码;
using IService; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IOC { class Program { static void Main(string[] args) { //标准版实现 IUser user = IOCConfig.Convert.IocConvert<IUser>(); user.Login(); Console.Write("\n"); //定制版实现 IUser user1 = IOCConfig.Convert.IocConvert<IUser>(1); user1.Login(); //标准定制只需要传相应的用户编号进去,这样前端代码都不会有任何改动. Console.Read(); } } }
注:前端需要引用相应的定制层的bin