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框架,自己以後多體會體會。不明白的留言交流。。。