• 隐藏在.NET中的IoC?


    因为最近在看Pico的一些资料,所以对IoC(或者叫Dependency Injection)相关的其他东东也关注了一下。

    如果对IoC不熟悉,你可以在今年第三期的《程序员》上面,找到一篇Martin Fowler写的介绍文章。英文原文在这里

    在Java平台上,基于IoC的轻量级Container已经不少了,像大家熟悉的SpringPicoContainer(NanoContainer)、Apache Avalon(此Avalon可不是Longhorn里面的那个Avalon)等等,但是.NET平台下除了一个Pico的移植和Spring作者开发Spring.Net的计划外,就少有所见了。

    当然有人很不服气,这篇文章的作者认为,IoC根本不是什么新概念,在2000年.NET的测试版里面,就可以看到IoC的影子了。在System.ComponentModel下面,就隐藏着IComponent、IContainer、ISite、IServiceProvider、IServiceContainer等接口和相应的默认实现。

    模仿Martin Fowler那篇文章中的代码,我用这些接口和默认实现写了一个IoC的“最小实现”,除了创建了一个新的MyServiceContainer类用来对ServiceContainer做了一下包装之外,其他全部是利用的.Net Framework本身提供的类和接口。

    // 创建一个Container
    IServiceContainer container = new MyServiceContainer();

    // 在Container中注册新的组件
    container.AddService(typeof(IMovieFinder), new DefaultMovieFinder());
    container.AddService(typeof(IMovieLister), new DefaultMovieLister());


    // 也可以从Container中删除组件
    //container.RemoveService(typeof(IMovieFinder));

    // 从Container中获取指定接口的组件后调用其功能
    IMovieLister lister = (IMovieLister) container.GetService(typeof(IMovieLister));
    if (lister != null)
    {
        lister.ListMovieByName("kaneboy");
    }


    注意上面代码中,在注册新的组件时,仍然用的HardCode创建新的实例,这里仅作为演示(通常实例类型是放在配置文件中或者完全按照配置文件来自动在Container中创建Component)。

    再来看看DefaultMovieFinder的实现:

    public class DefaultMovieFinder : System.ComponentModel.Component, IMovieFinder
    {
        public String[] FindByName(String name)
        {
            return new String[1] {"Matrix"};
        }
    }


    DefaultMovieFinder是一个实现了IMovieFinder接口并从System.ComponentModel.Component继承下来的类。

    public class DefaultMovieLister : System.ComponentModel.Component, IMovieLister
    {
        public void ListMovieByName(String name)
        {
            IMovieFinder finder = (IMovieFinder) this.Site.GetService(typeof(IMovieFinder));
            if (finder != null)
            {
                foreach(String movie in finder.FindByName(name))
                {
                    Console.WriteLine(movie);
                }
            }
        }
    }


    上面是DefaultMovieLister的实现,它是一个实现了IMovieLister并从System.ComponentModel.Component继承下来的类。在ListMovieByName()方法中,它通过Component类自带的Site属性(一个实现了ISite接口的类)来获得了Container中所需的Component。

    如果对完整源码感兴趣,可以在这里下载完整的源码项目文件。

  • 相关阅读:
    C#基础
    C#基础
    Sqlserver数据库备份和还原
    C#基础
    Python3学习笔记4
    Python3学习笔记3
    调用接口Post xml和json数据的通用方法
    Python3学习笔记2
    Python3学习笔记1
    常见的PHP函数代码性能对比
  • 原文地址:https://www.cnblogs.com/kaneboy/p/2436774.html
Copyright © 2020-2023  润新知