• 自己写一个依赖注入容器Container


    前言:在平时的写代码中为了解耦、方便扩展,经常使用一些DI容器(如:Autofac、Unity),那是特别的好用。

    关于它的底层实现代码 大概是这样。

    一、使用依赖注入的好处

      关于使用依赖注入创建对象的好处网上一找就是一大堆(低耦合、可配置等),这里就不复制粘贴了。

    二、使用XML+Assembly实现可配置的Container

    namespace com.cqgc.TestSys.Core
    {
        public class Container
        {
            private static Container instance;//实例
            private static XDocument xml;//UI层的服务实现配置文件实例
    
            public static Container Instance//全局IOC窗口实例,单例模式
            {
                get
                {
                    if (instance == null)
                    {
                        instance = new Container();
                    }
                    if (xml == null)
                    {
                        //读取UI层的服务实现配置文件
                        xml = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "/Configuration/Service.xml");
                    }
                    return instance;
                }
            }
    
            /// <summary>
            /// 向外提供创建对象的方法
            /// </summary>
            /// <typeparam name="T">Service</typeparam>
            /// <returns></returns>
            public T Resolve<T>()
                where T : class
            {
                return GetComponentInstance<T>(typeof(T).Name);
            }
    
            /// <summary>
            /// 通过XMl中的Service名创建对应的业务逻辑实体
            /// </summary>
            /// <typeparam name="T">Component</typeparam>
            /// <param name="service">Service名字</param>
            /// <returns>Component</returns>
            public T GetComponentInstance<T>(string service)
                where T : class
            {
                //没找到配置文件
                if (xml == null)
                {
                    throw new ArgumentNullException("没找到配置文件"+ nameof(xml));
                }
                //在UI层的服务实现配置文件根据接口文件名读取实现接口文件的业务逻辑实体
                var element = (from p in xml.Root.Elements("element")
                               where p.Attribute("Id").Value.Equals(service)
                               select new
                               {
                                   serviceNamespace = p.Attribute("Service").Value,
                                   classNamespace = p.Attribute("Class").Value
                               }).FirstOrDefault();
    
                //没找到配置节点
                if (string.IsNullOrEmpty(element.classNamespace))
                {
                    throw new Exception("配置文件结点" + service + "出错!");
                }
                string[] configs = element.classNamespace.Split(',');
    
                //XML配置中接口和业务逻辑实体不成对
                if (configs.Length != 2)
                {
                    throw new Exception("配置文件结点" + service + "出错!");
                }
    
                ProxyGenerator generator = new ProxyGenerator();//代码生成器
                T t = (T)Assembly.Load(configs[1]).CreateInstance(configs[0]);//根据配置文件实例化一个对象
    
                return t;
            }
    
            //释放资源
            public void Dispose()
            {
                instance = null;
                xml = null;
            }
        }
    }

     三、XML

    <?xml version="1.0" encoding="utf-8" ?>
    <root>
        <element Id="IUserService" Service="com.cqgc.TestSys.Service.IUserService, com.cqgc.TestSys.Service" Class="com.cqgc.TestSys.Component.UserComponent, com.cqgc.TestSys.Component"></element>
      <element Id="ISysUserService" Service="com.cqgc.TestSys.Service.ISysUserService, com.cqgc.TestSys.Service" Class="com.cqgc.TestSys.Component.SysUserComponent, com.cqgc.TestSys.Component"></element>
    </root>

    四、调用

    var _user=Container.Instance.Resolve<ISysUserService>();
  • 相关阅读:
    1系统负荷
    动画
    日常问题记录--JSP页面中通过<s:property value="#parameters.userName[0]>获取URL参数中文时为乱码的解决办法
    linux下替换一个文件中的所有中文字符的方法
    日常问题记录--getJSON函数不执行回调函数的原因总结
    日常问题记录-- java.util.NoSuchElementException
    日常问题记录--POST时,struts2的 request.getParameter找不到参数
    日常问题记录--nested exception is java.lang.NoClassDefFoundError: org/apache/oro/text/regex/MalformedPatternExcept
    mysql系统搭建互备DB(双主)记录
    使用forEach函数绑定函数的上下文
  • 原文地址:https://www.cnblogs.com/Innocent-of-Dabber/p/9722836.html
Copyright © 2020-2023  润新知