先看看 IoC百度百科

优化过程

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            //场景 某公司客服要回访一些客户
            //刚开始 回访的方式只有 打电话
            //简单的实现
            CustomerService1 cs1 = new CustomerService1();
            cs1.Call();
        }
    }
    public class CustomerService1
    {
        public string Call()
        {
            return "打电话";
        }
    }
}
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            //后来又添加了发短信的回访方式
            //考虑到以后还可能增加回访方式
            //而且为了不改动Main函数代码 我们将封装回访方法
            //但是这样只是将回访方式将造成的改动下移到了 Customer2里面了
            //然后将回访方式的选择放到配置文件appconfig里面 用户可以设置默认的回访方式
            CustomerService2 cs2 = new CustomerService2();
            string Method = System.Configuration.ConfigurationManager.AppSettings["Method"];
            cs2.Visit(Method);
        }
    }
    public class CustomerService2
    {
        public string Visit(string Method)
        {
            string result = "Not Found";
            switch (Method)
            {
                case "Call":
                    result = Call();
                    break;
                case "SMS":
                    result = SMS();
                    break;
            }
            return result;
        }
        private string Call()
        {
            return "打电话";
        }
        private string SMS()
        {
            return "发短信";
        }
    }
}
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string Method = System.Configuration.ConfigurationManager.AppSettings["Method"];

            //下来我们继续减少功能变化造成的代码修改
            //如果增加功能虽然Main不用更改但是CustomerService2还是得改动
            //我们接下来继续优化CustomerService
            //见CustomerService3 内部注释 Main已经不需改动
            CustomerService3 cs3 = new CustomerService3();
            cs3.Visit(Method);
        }
    }
    public class CustomerService3
    {
        public string Visit(string Method)
        {
            //参照CustomerService2可以发现如果 添加回访方式 就必须在Visit的Switch里面加一个case 再加一功能方法
            //我们先分离这些方法
            //将他们接口化
            //可以发现方法的实现被抽象出来了
            //进一步用户swith请看 CustomerService4
            IServiceMethod servicemethod = null;
            switch (Method)
            {
                case "Call":
                    servicemethod = new CallMethod();
                    break;
                case "SMS":
                    servicemethod = new SMSMethod();
                    break;
            }
            return servicemethod.Vist();
        }
    }
    public class CallMethod
    {
        public string Vist()
        {
                 return "打电话";
        }
    }
    public class SMSMethod
    {
            public string Vist()
           {
                  return "发短信";
            }
     }
}    
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string Method = System.Configuration.ConfigurationManager.AppSettings["Method"];

            CustomerSerive4 cs4 = new CustomerSerive4();
            cs4.Visit(Method);
        }
    }

    public class CustomerSerive4
    {
        public string Visit(string Method)
        {
            //为了根据Method来实例化方法 并进行调用 我们需要引入 反射机制
            //根据我们原来的命令规范 Method参数+"Method"就是我们需要找的类 由于在我们在同一个程序集里面 所以可以直接用Test 后面考虑建一个映射配置来查找
            //这样我们就把回访方式的增加带来的代码的更改 从Main下放到了CustomerService 又从CustomerService下方到了IServiceMetod的实现类中
            //最后一步就是将IServiceMethod实现类的增加带来项目的重新生成dll的重新编译 重新发布问题了
            //请看 CustomerService5
            IServiceMethod servicemethod = Activator.CreateInstance("Test", Method + "Method") as IServiceMethod;
            return servicemethod.Vist();
        }
    }
       public interface IServiceMethod
       {
             string Vist();
       }
       public class CallMethod : IServiceMethod
       {
             public string Vist()
             {
                   return "打电话";
              }
       }
       public class SMSMethod : IServiceMethod
       {
            public string Vist()
            {
                return "发短信";
            }
        }
}
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string Method = System.Configuration.ConfigurationManager.AppSettings["Method"];

            CustomerService5 cs5 = new CustomerService5();
            cs5.Visit(Method);

        }
    }
    public class CustomerService5
    {
        public string Visit(string Method)
        {
            //解决重新编译的方法就是
            //1.将IServiceMetod接口独立成一个项目 另一个名称空间 使之独立存在 注意此处 IServiceMetod是TestInterface名称空间(TestInterface.dll里面)
            //2.将CallMethod、SMSMethod等IServiceMetod接口的实现类也独立成一个项目TestMethodImp (TestMethodImp.dll)里面
            TestMethodInterface.IServiceMethod servicemethod = Activator.CreateInstance("TestMethodImp", Method+"Method") as TestMethodInterface.IServiceMethod;
            return servicemethod.Vist();
        }
    }

    public interface IServiceMethod
    {
        string Vist();
    }
    public class CallMethod : IServiceMethod
    {
        public string Vist()
        {
            return "打电话";
        }
    }
    public class SMSMethod : IServiceMethod
    {
        public string Vist()
        {
            return "发短信";
        }
    }

}

namespace TestMethodInterface
{
    public interface IServiceMethod
    {
        string Vist();
    }
}
namespace TestMethodImp
{
    public class CallMethod : TestMethodInterface.IServiceMethod
    {
        public string Vist()
        {
            return "打电话";
        }
    }
    public class SMSMethod : TestMethodInterface.IServiceMethod
    {
        public string Vist()
        {
            return "发短信";
        }
    }
}

框架后

主要方法

        /// <summary>
        /// 创建对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="Key">对象关键字</param>
        public static T CreateStance<T>(string Key)

        /// <summary>
        /// 创建一个对象 单例模式
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="Key">对象关键字</param>
        public static T CreateSingle<T>(string Key)  

xml配置

<?xml version="1.0" encoding="utf-8" ?>
<IoCMap>
  <Map>
    <Key>Data</Key>
    <Value>Test_Business.Data</Value>
  </Map>
  <Map>
    <Key>Main</Key>
    <Value>Test_Business.Main</Value>
  </Map>
  <Map>
    <Key>Data2</Key>
    <Value>Test_Business2.Data</Value>
  </Map>
  <Map>
    <Key>Main2</Key>
    <Value>Test_Business2.Main</Value>
  </Map>
</IoCMap>

 实现主要代码

Assembly.CreateInstance(ObejctName);
Assembly.LoadFrom(AssemblePath);

实战使用

第一步:创建接口

/// <summary>
    /// 数据接口
    /// </summary>
    public interface IData
    {
        /// <summary>
        /// 数据
        /// </summary>
        string DataString { get; set; }
    }

    /// <summary>
    /// 程序运行接口
    /// </summary>
    public interface IMain
    {
        /// <summary>
        /// 处理方法
        /// </summary>
        /// <param name="data">数据类型</param>
        string ProcData(IData data);
    }

第二部:创建两个不同程序集的实现类

 /// <summary>
    /// 程序运行接口实现类一号
    /// </summary>
    public class Main : Test_InterFace.IMain
    {
        /// <summary>
        /// 处理方法实现
        /// </summary>
        public string ProcData(Test_InterFace.IData data)
        {
            return "我是一号处理方法" + data.DataString;
        }
    }
        /// <summary>
    /// 数据实现类一号
    /// </summary>
    public class Data : Test_InterFace.IData
    {
        private string _datastring;
        /// <summary>
        /// 实现数据属性
        /// </summary>
        public string DataString
        {
            get
            {
                return _datastring;
            }
            set
            {
                _datastring = "我是数据一号" + value;
            }
        }
    }

2.

/// <summary>
    /// 程序运行接口实现类二号
    /// </summary>
    public class Main2:IMain
    {
        /// <summary>
        /// 处理方法实现
        /// </summary>
        public string ProcData(IData data)
        {
            return "我是二号处理方法" + data.DataString;
        }
    }
     /// <summary>
    /// 数据实现类二号
    /// </summary>
    public class Data2:IData
    {
        private string _dataString;
        /// <summary>
        /// 实现数据属性
        /// </summary>
        public string DataString
        {
            get
            {
                return _dataString;
            }
            set
            {
                _dataString = "我是数据二号" + value;
            }
        }
    }

第三部:写配置

<?xml version="1.0" encoding="utf-8" ?>
<IoCMap>
  <Map>
    <Key>Data</Key>
    <Value>Test_Business.Data</Value>
  </Map>
  <Map>
    <Key>Main</Key>
    <Value>Test_Business.Main</Value>
  </Map>
  <Map>
    <Key>Data2</Key>
    <Value>Test_Business2.Data2</Value>
  </Map>
  <Map>
    <Key>Main2</Key>
    <Value>Test_Business2.Main2</Value>
  </Map>
</IoCMap>

第四部:开始调用

    class Program
    {
        static void Main(string[] args)
        {
            IMain main = IoCFactory.CreateStance<IMain>("Main");
            IData data = IoCFactory.CreateSingle<IData>("Data");
            Console.WriteLine(main.ProcData(data));
            Console.ReadKey();
        }
    }

运行结果:

更改配置:

<?xml version="1.0" encoding="utf-8" ?>
<IoCMap>
  <Map>
    <Key>Data</Key>
    <Value>Test_Business2.Data2</Value>
  </Map>
  <Map>
    <Key>Main</Key>
    <Value>Test_Business2.Main2</Value>
  </Map>
  <Map>
    <Key>Data2</Key>
    <Value>Test_Business.Data</Value>
  </Map>
  <Map>
    <Key>Main2</Key>
    <Value>Test_Business.Main</Value>
  </Map>
</IoCMap>

结果:

以后的扩展只需引用接口 实现接口 放到程序的bin目录 就可以了

欢迎大牛指点、吐槽。

需要完整代码的留言 O(∩_∩)O谢谢 

自己动手写框架——IoC的实现的更多相关文章

  1. 一起写框架-Ioc内核容器的实现-基础功能-ComponentScan(四)

    功能说明 该步骤实现的功能包括: 1. 启动程序时,将@ComponentScan加载的类,创建对象并放在容器里面. 2. 通过ApplicatoinContext的getBean()方法获得容器里面 ...

  2. 一起写框架-Ioc内核容器的实现-基础API的定义(三)

    Ioc内核要解决的问题 1.被调用方,在程序启动时就要创建好对象,放在一个容器里面. 2.调用方使用一个接口或类的引用(不用使用new),就可以创建获得对象. 解决这个两个问题的思路 1.定义一个对象 ...

  3. 一起写框架-Ioc内核容器的实现-基础功能-容器对象名默认首字母小写(八)

    实现功能 --前面实现的代码-- 默认的对象名就类名.不符合Java的命名规范.我们希望默认的对象名首字母小写. 实现思路 创建一个命名规则的帮助类.实现将对大写开头的对象名修改为小写开头. 实现步骤 ...

  4. 一起写框架-Ioc内核容器的实现-基础功能-ComponentScan支持组件注解限制(七)

    实现功能 以上的代码我们发现.我们都是将@ComponentScan扫描的路径下的所有类都加载到容器中的. 而实际需求,我们并不希望所有的类都创建对象,而是加了组件注解@Controller,@Ser ...

  5. 一起写框架-Ioc内核容器的实现-基础功能-getBean(五)

    实现的功能 1. 启动程序时,将@ComponentScan加载的类,创建对象并放在容器里面.(查看上一篇文) 2. 通过ApplicatoinContext的getBean()方法获得容器里面的对象 ...

  6. 《自己动手写框架2》:用200行的DBF解析器来展示良好架构设计

    因为工作关系.须要工作其中,须要读取DBF文件.找了一些DBF读取开源软件,要么是太过庞大,动不动就上万行.要么是功能有问题,编码,长度,总之是没有找到一个很爽的. 在万般无奈之下,我老人家怒从心头起 ...

  7. 一起写框架-Ioc内核容器的实现-基础功能-ComponentScan支持多包扫描(六)

    实现功能 1.我们看到@ComponentScan注解一个开始定义就是需要支持,扫描多个包,将多个包的类名获取到.现在就实现这个功能. 实现思路 根据传入的字符串数组,获得多个包下的类全限制名. 实现 ...

  8. 自己动手写Spring框架--IOC、MVC

    对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC.MVC.AOP.ORM(batis). 下面我想简单介绍一下我写的轻量级的 S ...

  9. 自己动手实现Spring IoC框架

    钻研Spring 源码也有一段时间了,对Spring IoC的实现原理理解算是比较透彻了,要实现一款IoC容器,简单的概括无非需要以下几个步骤: 1.定义用来描述bean的配置的Java类,例如我们有 ...

随机推荐

  1. Expanding Rods

    http://poj.org/problem?id=1 #include<cstdio> #include<cstring> #include<cmath> #in ...

  2. 等待事件--db file sequential read

    对于最小化db file sequential read 事件所带来的影响,你可以做的另一件事情是减少AVERAGE_WAIT时间. 这是会话必须等待从磁盘提取单块的平均时间,这些信息可以从v$ses ...

  3. lr 增强窗格中,如何生成调试信息?

    我是根据电子书来操作的, 如何生成调试信息?在测试运行的某些时候,经常需要向输出设备发送消息,指出当前位置和其他信息.这些输出消息会出现在回放日志和 Controller 的输出窗口中.可以发送标准输 ...

  4. MySQL如何利用索引优化ORDER BY排序语句 【转载】

    本文转载自:http://blog.csdn.net/ryb7899/article/details/5580624  .感谢相关作者. MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执 ...

  5. Oralce新建数据库、新建远程登录用户全过程

    Oracle安装完后,其中有一个缺省的数据库,除了这个缺省的数据库外,我们还可以创建自己的数据库.     对于初学者来说,为了避免麻烦,可以用'Database Configuration Assi ...

  6. iOS CoreBluetooth 教程

    去App Store搜索并下载“LightBlue”这个App,对调试你的app和理解Core Bluetooth会很有帮助. ================================ Cor ...

  7. SKPhysicsJointLimit类

    继承自 NSObject 符合 NSCoding(SKPhysicsJoint)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit. ...

  8. ndroid调用平台功能具体技巧分享

    Android操作系统那个可以通过调用手机平台来实现一些特定的功能,诸如网页的显示,邮件的发送等等.那么今天就为大家总结了几个Android调用平台功能的应用技巧,帮助大家增加编程经验. Androi ...

  9. Lecture Halls

    Lecture Halls (会议安排)   时间限制(普通/Java):1000MS/10000MS     运行内存限制:65536KByte 总提交: 38            测试通过: 2 ...

  10. 《火球——UML大战需求分析》(第1章 大话UML)——1.4 如何学好UML?

    说明: <火球——UML大战需求分析>是我撰写的一本关于需求分析及UML方面的书,我将会在CSDN上为大家分享前面几章的内容,总字数在几万以上,图片有数十张.欢迎你按文章的序号顺序阅读,谢 ...