先来看看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框架,自己以后多体会体会。不明白的留言交流。。。