欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入

程序员文章站 2022-12-09 17:33:57
依赖注入主要是一种结构性的模式,注重的是类与类之间的结构,它要达到的目的就是设计原则中最少知道和合成复用的原则,减少内部依赖,履行单一职责,最终就是强解耦。依赖注入目前最好的实现就是依赖注入容器。 Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入 ......
  1. 简介

  依赖注入主要是一种结构性的模式,注重的是类与类之间的结构,它要达到的目的就是设计原则中最少知道和合成复用的原则,减少内部依赖,履行单一职责,最终就是强解耦。依赖注入目前最好的实现就是依赖注入容器。

  unity是微软patterns & practices团队所开发的一个轻量级的,并且可扩展的依赖注入(dependency injection)容器,它支持常用的三种依赖注入方式:构造器注入(constructor injection)、属性注入(property injection),以及方法调用注入(method call injection).

  本项目基于unity,减少内部依赖,实现项目解耦。基于lgpl协议开源。

 

  2.项目源码

using microsoft.practices.unity;
using microsoft.practices.unity.configuration;
using system;
using system.collections.generic;
using system.configuration;
using system.linq;
using system.text;

namespace shiquan.unity
{
    /// <summary>
    /// unity 辅助对象
    /// </summary>
    public class unityhelper
    {
        #region 单例

        private static readonly unityhelper _instance = new unityhelper();
        /// <summary>
        /// unity 辅助对象
        /// </summary>
        public static unityhelper instance
        {
            get
            {
                return _instance;
            }
        }
        #endregion

        private readonly iunitycontainer _container = new unitycontainer();
        /// <summary>
        /// 获取容器
        /// </summary>
        public iunitycontainer container
        {
            get { return _container; }
        }
        private unityhelper()
        {
            var configuration = configurationmanager.getsection(unityconfigurationsection.sectionname) as unityconfigurationsection;
            if (configuration != null)
            {
                configuration.configure(_container);
            }
        }

        #region 获取对应接口的具体实现类
        /// <summary>
        /// 获取实现类(默认映射)
        /// </summary>
        /// <typeparam name="t">接口类型</typeparam>
        /// <returns>接口</returns>
        public t getresolve<t>()
        {
            return _container.resolve<t>();
        }
        /// <summary>
        /// 获取实现类(默认映射)带参数的
        /// </summary>
        /// <typeparam name="t">接口类型</typeparam>
        /// <param name="parameter">参数</param>
        /// <returns>接口</returns>
        public t getresolve<t>(params parameteroverride[] parameter)
        {
            return _container.resolve<t>(parameter);
        }
        /// <summary>
        /// 获取实现类(指定映射)带参数的
        /// </summary>
        /// <typeparam name="t"></typeparam>
        /// <param name="name"></param>
        /// <param name="parameter"></param>
        /// <returns>接口</returns>
        public t getresolve<t>(string name, params parameteroverride[] parameter)
        {
            return _container.resolve<t>(name, parameter);
        }
        #endregion

        #region 判断接口是否被注册了
        /// <summary>
        /// 判断接口是否被实现了
        /// </summary>
        /// <typeparam name="t">接口类型</typeparam>
        /// <returns>bool</returns>
        public bool isregistered<t>()
        {
            return _container.isregistered<t>();
        }
        /// <summary>
        /// 判断接口是否被实现了
        /// </summary>
        /// <typeparam name="t">接口类型</typeparam>
        /// <param name="name">映射名称</param>
        /// <returns></returns>
        public bool isregistered<t>(string name)
        {
            return _container.isregistered<t>(name);
        }
        #endregion
    }
}

 

  源码地址:https://gitee.com/shiquan25/shiquan.unity

  3.调用示例

  下面演示调用此程序示例:

  首先我们创建数据操作基础项目,定义idatabase接口,定义一获取名称的方法。

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;

namespace shiquan.dataaccess
{
    /// <summary>
    /// 定义接口
    /// </summary>
    public interface idatabase
    {
        string name { get; }
    }
}

 

       创建sqlserver项目,定义sqldatabase实现idatabase接口。

using shiquan.dataaccess;
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;

namespace shiquan.dataserver
{
    /// <summary>
    /// 实现
    /// </summary>
    public class sqldatabase : idatabase
    {
        public string name
        {
            get { return "sqldatabase"; }
        }
    }
}

 

  创建mysql 项目,定义mysqldatabase实现idatabase接口。

using shiquan.dataaccess;
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;

namespace shiquan.datamysql
{
    /// <summary>
    /// 实现
    /// </summary>
    public class mysqldatabase : idatabase
    {
        public string name
        {
            get { return "mysqldatabase"; }
        }
    }
}

  创建数据操作工厂项目,定义datafactory实现根据参数调用不同的实现类。

using shiquan.dataaccess;
using shiquan.datamysql;
using shiquan.dataserver;
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;

namespace shiquan.datarepository
{
    /// <summary>
    /// 数据工厂
    /// </summary>
    public class datafactory
    {
        /// <summary>
        /// 获取数据操作对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static idatabase getdatabase(string name)
        {
            switch (name)
            {
                case "mysql":
                    {
                        return new mysqldatabase();
                    }
                case "sqlserver":
                default:
                    {
                        return new sqldatabase();
                    }
            }
            
        }
    }
}

  创建console程序进行测试

using shiquan.dataserver;
using shiquan.datamysql;
using shiquan.unity;
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;
using shiquan.dataaccess;
using shiquan.datarepository;

namespace consoleapp
{
    class program
    {
        static void main(string[] args)
        {
            console.writeline("实例并调用sql server...");
            idatabase sqlserver = datafactory.getdatabase("sqlserver");
            console.writeline(sqlserver.name);

            console.writeline("实例并调用mysql...");
            idatabase mysql = datafactory.getdatabase("mysql");
            console.writeline(mysql.name);

            console.readline();
        }
        
    }
}

  项目结构大概是这样的:

基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入

  运行结果:

基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入

  4.unity调用

  假设此时,如果我们需要实现其他数据库操作,实现idatabase接口时,除了增加其他数据库操作项目,还得修改、调整数据操作工厂项目。

  但是如果我们的数据操作工厂项目改用依赖注入的方式,工厂项目是不需要引用sqlserver项目、mysql项目及其他数据库操作项目,可以不改动工厂项目的情况下,主程序直接在配置文件中添加相应的操作项目及类,以达到面向接口开发、减少内部依赖、实现项目解耦。

  项目添加程序包

 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入

  主程序配置文件(app.config或web.config)增加配置

<configsections>
    <section name="unity" type="microsoft.practices.unity.configuration.unityconfigurationsection,microsoft.practices.unity.configuration" />
  </configsections>

 

  配置接口,接口实现对象

 

<unity>
    <typealiases>
      <typealias alias="idatabase" type="shiquan.dataaccess.idatabase,shiquan.dataaccess" />
      <typealias alias="sqlserver" type="shiquan.dataserver.sqldatabase,shiquan.dataserver" />
      <typealias alias="mysql" type="shiquan.datamysql.mysqldatabase,shiquan.datamysql" />
    </typealiases>
    <containers>
      <container>
        <type type="idatabase" mapto="sqlserver" name="sqlserver"></type >
        <type type="idatabase" mapto="mysql" name="mysql"></type >
      </container>
    </containers>
  </unity>

  工厂项目实例调用

 

/// <summary>
        /// 获取数据操作对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static idatabase getdatabase(string name)
        {
            //switch (name)
            //{
            //    case "mysql":
            //        {
            //            return new mysqldatabase();
            //        }
            //    case "sqlserver":
            //    default:
            //        {
            //            return new sqldatabase();
            //        }
            //}
            return shiquan.unity.unityhelper.instance.getresolve<idatabase>(name);
        }

  运行测试结果达到工厂模式同样的效果,并且可扩展性更强、项目解耦,减少项目依赖。

 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入

  至此,项目介绍完毕,更多精彩,且听下回分解!