1. 程式人生 > >.NET之IOC控制反轉運用

.NET之IOC控制反轉運用

string 標準 需要 對象 ati ext [] 根據 mar

當前場景:

如果有不同的用戶。使用同一個系統。而不同的客戶有某些不同的需求。在不改變系統主體的情況下,可以直接使用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

.NET之IOC控制反轉運用