zoukankan      html  css  js  c++  java
  • 自己写一个依赖注入容器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>();
  • 相关阅读:
    2.NET Core设定数据库种子
    1.ASP.NET Core 中向 Razor Pages 应用添加模型
    获取文件夹目录下的文件信息
    dataGridView读写文本
    C# winform 启动外部程序
    netcore访问本地磁盘
    c#利用定时器自动备份数据库(mysql)
    c#mysql数据库备份还原
    Linux之旅(二)
    Linux之旅
  • 原文地址:https://www.cnblogs.com/Innocent-of-Dabber/p/9722836.html
Copyright © 2011-2022 走看看