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 BindCache
                {
                    get;
                    set;
                }
                private InjectorFactory() {
                    BindCache = new Dictionary();
                }
                public void Bind()
                {
                    if (!BindCache.ContainsKey(typeof(T)))
                    {
                        BindCache.Add(typeof(T), typeof(V));
                    }
                    else
                    {
                        BindCache[typeof(T)] = typeof(V);
                    }
                }
                public T CreateInstance() where T:new()
                {
                     var a=new T();

                     //注入此类内部属性
                     KeyValuePair[] pairs = new KeyValuePair[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();
                InjectorFactory.Instance.Bind();
                //进入框架生命周期
                var test = InjectorFactory.Instance.CreateInstance();
                //调用此类的方法
                Console.WriteLine(test.cls.GetName());
                Console.ReadKey();
            }
        }
    }

说明:

1.上面的每一步都是一个类,直接复制就能使用

2.绑定的类型相同(比方说IMyClass,被绑定了两次,那么返回最后绑定的那个类型)

好了,上面就简单的实现了StrangeIOC框架,自己以后多体会体会。不明白的留言交流。。。

你可能感兴趣的:(C#)