.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 = ) where T : class
{
string assemblyName = string.Empty ;//程序集名称
if (userId==)
{
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>();
user1.Login(); //标准定制只需要传相应的用户编号进去,这样前端代码都不会有任何改动.
Console.Read(); }
}
}

注:前端需要引用相应的定制层的bin

上一篇:CentOS7利用systemctl添加自定义系统服务【转】


下一篇:Signalr指定Websocket方式跨域数据传输