• IOC 容器初始化


    WebApi 插件式构建方案:IOC 容器初始化

    一般来说,一个现代化的网站加载流程是这样的:程序集加载后,我们会初始化 IOC 容器,以便于接下来解析对象用。

    我们插件式的开发,这一步更为重要。这是因为在开发阶段,这些程序集以及 IOC 配置都是分属于多个解决方案的,在部署前很可能还没有连调。如何在集成在一起后,保证起码的可用性,是很关键的一个步骤。研究稍微深一点的同学,应该很清楚 WebApi 框架本身就集成了一个 IOC 框架用于对象的生成。我们要做的工作就是在此基础上扩展,把我们要额外注入的东西添加进去。

    IOC 容器选型:Unity

    选用 Unity 无可厚非,公司一直在用并且也没什么想换的意思。在第一篇文章里,@elder 说 MEF 不错,但是大环境下,确实没见过有人在用。包括微软自家的 MVC 和 WebApi,基本思想都是实现 CommonServiceLocation。如果有企业级的应用在使用 MEF,不妨通过私信告诉我。我也想看看这个集成在 .Net 4 中的微软亲儿子,到底是骡子还是马。

    不管怎么说,多一种选择总是没错的。至于其它的 IOC 框架,从对 CommonServiceLocation 做适配上来看,基本上都是大同小异,只是获取类型注册的方式有所不同而已。

    这里我选用现成的 Unity.WebApi 组件将 WebApi 自身的 IOC 容器扩展到 Unity 中(反编译后可以发现就两个类,直接把代码拷贝出来,贴到项目里也是可以的)。

    容器注册项加载约定

    对于一个 IOC 容器来说,通过配置文件加载注册项都是不可或缺的。连 Ninject 这种奇葩,都有第三方对其扩展了配置文件支持。在编程中,我个人特别讨厌不想干的代码侵入,所以一般我会把 IOC 的注入写在配置文件中:一方面代码干净了,另一方面,一个简单的配置修改,就可以不用重新编译代码了,这不就是 IOC 的本质吗?

    配置文件可以多次附加配置到一个 IOC 容器实例上很必要,这样我就可以连续把多个配置文件的注册项添加到一个实例上。事实上,IOC 容器的实例,全局有且只有一个的时候才有用。回到咱们的 Unity 上面,很不幸的是,Unity 支持这个要求,呵呵。

    额外的,为了项目整体上一致,我为 Unity 的配置文件约定:

    • Unity 配置文件名称为 unity.config
    • 存放路径为:相对当前程序集所在目录的 Configurationunity.config,这样只需要调整生成时总是复制就可以了。

    注:这里如果你想灵活一些,可以在上一节的配置文件中添加你的 Unity 配置文件路径设置信息。

    部分源代码:自然语义

    额外的,在 Global 中需要用 Unity.WebApi 把扩展点挂接上。下面是 IOC 加载各个模块配置的事情代码:

    public interface IContainerConfiguration
    {
      object Config(object container);
    }
    
    public class DefaultContainerConfiguration : IContainerConfiguration
    {
        public object Config(object container)
        {
            var data = new List<string>();
    
            data.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configuration\unity.config"));
    
            foreach(var item in DynamicModule.Instance.Modules)
            {
                data.Add(Path.Combine(item.BaseDirectory, "Configuration\unity.config"));
            }
        }
    }

    补充:程序集加载

    上一节写完以后,有人私信问我加载顺序的问题。在这里补充一下,程序集的加载和顺序是无关的:我可以先加载接口的实现程序集,再加载接口程序集。但是还有一些需要注意的地方:

    • 程序集加载时,首先加载的程序集 B 如果引用了后续加载的程序集 A,加载不会产生错误。
    • 后续被引用的程序集 A 被加载后,先前加载的程序集 B 中的类型就可以正常访问了。
    • 在后续程序集 A 加载之前,如果有使用 B 中的程序集,就会提示出错;后续程序集 A 加载后,这个错误仍将继续存在,且一直存在。

    所有正确的做法是:程序集加载可以无序进行,但是一定要加载全部程序集后,再进行后续操作。

     

     

     

     
    标签: IOCWebApi

  • 相关阅读:
    Mac下mysql出现错误:ERROR 1055 (42000)
    单表查询
    外键的变种 三种关系
    Java8中Lambda表达式详解
    Java中的比较器Comparable、Comparator
    Java创建线程的方法
    java日期格式化
    Docker容器如何修改hosts
    使用postman可以正常访问,但是在应用中返回415状态码
    使用tcpdump进行抓包
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4151908.html
Copyright © 2020-2023  润新知