1. 程式人生 > >StrangeIOC MVCS框架介紹及簡單實現

StrangeIOC MVCS框架介紹及簡單實現

先來看看MVC

MVC(Model-View-Controller)是最老牌的的思想,其中Model就是作為資料管理者,View作為資料展示者,Controller作為資料加工者,Model和View又都是由Controller來根據業務需求調配,所以Controller還負擔了一個數據流調配的功能。

        分工總結: 
        檢視(View):使用者介面 
        控制器(Controller):業務邏輯及處理 
        模型(Model):資料儲存

啥是MVCS架構

StrangeIOC採用MVCS(資料模型 Model,展示檢視 View,邏輯控制 Controller,服務Service)結構,通過訊息/訊號進行互動和通訊。整個MVCS框架跟flash的robotlegs基本一致

        分工總結: 
        資料模型 Model:主要負責資料的儲存和基本資料處理
        展示檢視 View:主要負責UI介面展示和動畫表現的處理
        邏輯控制 Controller:主要負責業務邏輯處理,
        服務Service:主要負責獨立的網路收發請求等的一些功能。

幾個概念

1.IOC容器

IOC也被成為控制反轉,在StrangeIOC與許許多多框架通常用這種技巧實現一個容器,我們將程式碼內的依賴關係交給第三方(IOC容器)管理,需要什麼型別告訴工廠你要的型別,他會生產給你一個例項,簡而言之我們可以看作是一個用來new型別的工廠(參見設計模式之簡單工廠)

2.Bind

我們可以理解為往這個IOC工廠內新增介面與型別的對映

3.注入

也叫依賴注入(DI),這個注入的過程就是從IOC容器內取值的過程,注入的方式有很多 屬性注入,介面注入,方法注入,而下文我們著重看看如何實現一個屬性注入,StrangeIOC就是使用屬性注入,這也是很多初學者疑惑的地方,為什麼我寫了一個[Inject]就能獲取到例項。

例子

實現屬性注入

1.以模擬注入標籤,當然實際框架中也是這樣做的,現在把你向注入的型別都打上標籤把~

        using System;

        namespace StrangeIOC
        {
            [AttributeUsage( AttributeTargets.All,Inherited=false,AllowMultiple=true)]
           sealed class InjectAttribute:Attribute
            {
               readonly string positionalString;
               public InjectAttribute(string injectType)
               {
                   this.positionalString = injectType;
               }
               public InjectAttribute()
               { 

               }
            }
        }

2.實現一個簡單注入工廠 此類是一個單例(通過屬性器實現),來模擬注入框架,BindCache 為注入的型別列表,這裡我用泛型Bind來新增BindCache

        using System;
        using System.Collections.Generic;
        using System.Reflection;

        namespace StrangeIOC
        {
            public class InjectorFactory
            {
                private static InjectorFactory instance;
                public static InjectorFactory Instance
                {
                    get {
                        if (instance == null)
                            instance = new InjectorFactory();
                        return instance;
                    }
                }
                public Dictionary<Type, Type> BindCache
                {
                    get;
                    set;
                }
                private InjectorFactory() {
                    BindCache = new Dictionary<Type, Type>();
                }
                public void Bind<T, V>()
                {
                    if (!BindCache.ContainsKey(typeof(T)))
                    {
                        BindCache.Add(typeof(T), typeof(V));
                    }
                    else
                    {
                        BindCache[typeof(T)] = typeof(V);
                    }
                }
                public T CreateInstance<T>() where T:new()
                {
                     var a=new T();

                     //注入此類內部屬性
                     KeyValuePair<Type, PropertyInfo>[] pairs = new KeyValuePair<Type, PropertyInfo>[0];
                     object[] names = new object[0];
                     MemberInfo[] privateMembers = a.GetType().FindMembers(MemberTypes.Property,
                                                  BindingFlags.FlattenHierarchy |
                                                   BindingFlags.SetProperty |
                                                    BindingFlags.Public |
                                                     BindingFlags.NonPublic |
                                                     BindingFlags.Instance,
                                                     null, null);
                     foreach (var member in privateMembers)
                     {
                         object[] injections = member.GetCustomAttributes(typeof(InjectAttribute), true);
                         if (injections.Length > 0)
                         {
                             PropertyInfo point = member as PropertyInfo;
                             Type pointType = point.PropertyType;
                             point.SetValue(a, Activator.CreateInstance(BindCache[pointType]));
                         }
                     }
                     return a;
                }
            }
        }

3.基類或介面

    namespace StrangeIOC
    {
        public interface IMyClass
        {
            string GetName();
        }
    }

4.兩個類去實現這個介面

        namespace StrangeIOC
        {
            public class MyClass1:IMyClass
            {
                public string GetName()
                {
                    return " Inject MyClass1";
                }
            }
            public class MyClass2 : IMyClass 
            {
                public string GetName()
                {
                    return " Inject MyClass2";
                }
            }
        }

5.編寫一個測試類,我們注入它

        namespace StrangeIOC
        {
            public class Test
            {
                [Inject]
                public IMyClass cls { get; set; }
            }
        }

6.測試以下我們實現的注入工廠

    using System;

    namespace StrangeIOC
    {
        class Program
        {
            static void Main(string[] args)
            {
                //注入類型別
                InjectorFactory.Instance.Bind<IMyClass, MyClass1>();
                InjectorFactory.Instance.Bind<IMyClass, MyClass2>();
                //進入框架生命週期
                var test = InjectorFactory.Instance.CreateInstance<Test>();
                //呼叫此類的方法
                Console.WriteLine(test.cls.GetName());
                Console.ReadKey();
            }
        }
    }

說明:

1.上面的每一步都是一個類,直接複製就能使用

2.繫結的型別相同(比方說IMyClass,被綁定了兩次,那麼返回最後繫結的那個型別)

好了,上面就簡單的實現了StrangeIOC框架,自己以後多體會體會。不明白的留言交流。。。