.netCore3.0学习系列(二) -- Ioc容器服务依赖注入

首先定义注入所需的接口:

/// <summary>
/// 注入标识
/// </summary>
public interface INeedInject
{

}

/// <summary>
/// 忽略注入标识
/// </summary>
public interface INoNeedInject
{

}

/// <summary>
/// 此种情况下,服务类的实例是用的时候创建,用完后直接销毁。
/// </summary>
public interface ITransentInject : INeedInject
{

}

/// <summary>
/// 单个实例,这是寿命最长的,与天同寿。整个应用程序中仅用一个实例。
/// </summary>
public interface ISingleTonInject : INeedInject
{

}

/// <summary>
/// 它的生命周期在单个请求内,包括客户端与服务器之间随后产生的子请求,反正只要请求的会话结束了,就会清理。
/// </summary>
public interface IScopeInject : INeedInject
{

}

appsettings.json配置文件加上程序集节点:

"AppSettings": {"ServicesLib": {"LibName": "EFCore.Application.dll"}}


添加获取配置文件的帮助类(多种方式):

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IO;

namespace EFCore.Common
{
    public class Configs
    {
        private static IConfiguration _config;

        static Configs()
        {
            //从请求目录下获取文件appsettings.json值
            _config = new ConfigurationBuilder()
                 .SetBasePath(Directory.GetCurrentDirectory())
                 .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                 .Build();
        }

        /// <summary>
        /// 数据库链接字符串
        /// </summary>
        /// <param name="nameOfConn">连接字符串名</param>
        /// <returns></returns>
        public static string GetConnectionString(string connName = "SysDbConnStr")
        {
            return _config.GetConnectionString(connName);
        }

        /// <summary>
        /// 获取配置文件AppSettings节点下的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetSettingsValue(string key)
        {
            return _config.GetSection($"AppSettings:{key}").Value;
        }
    }
}


服务依赖实现:

public static class IocProvider
{
    /// <summary>
    /// 服务依赖容器
    /// </summary>
    public static IServiceProvider Instance { get; set; }

    /// <summary>
    /// 添加服务依赖
    /// </summary>
    /// <param name="service"></param>
    public static void AddServices(this IServiceCollection service)
    {
        //iNoNeedInject -> 需要添加到服务依赖的标识
        Type iNeedInject = typeof(INeedInject);
        //iNoNeedInject -> 当接口切换实现类时,在旧的实现类上实现这个接口就不会把旧的实现类添加到服务依赖
        Type iNoNeedInject = typeof(INoNeedInject);

        Type iTransentInject = typeof(ITransentInject);
        Type iScopeInject = typeof(IScopeInject);
        Type iSingletonInject = typeof(ISingleTonInject);

        var LibName = Configs.GetSettingsValue("ServicesLib:LibName");
        if (!LibName.IsEmpty())
        {
            var LibNameList = ExtConvert.ToStringArray(LibName, ',');
            foreach (var libName in LibNameList)
            {
                //加载服务程序集
                var assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + libName);
                //查找服务层的接口
                Type[] appServices = assembly.GetTypes().Where(t => t.IsInterface && iNeedInject.IsAssignableFrom(t) && t != iNeedInject && t != iTransentInject && t != iScopeInject && t != iSingletonInject).ToArray();
                foreach (var item in appServices)
                {
                    //查找服务层接口实现类
                    Type objType = assembly.GetTypes().Where(t => t.IsClass && item.IsAssignableFrom(t) && !iNoNeedInject.IsAssignableFrom(t)).SingleOrDefault();
                    if (objType != null)
                    {
                        IList<Type> inJectTypeList = objType.GetInterfaces().Where(i => i == iTransentInject || i == iScopeInject || i == iSingletonInject).ToList();
                        if (inJectTypeList.Count == 1)
                        {
                            Type inJectType = inJectTypeList.Single();
                            string inJectTypeName = inJectType.Name;
                            switch (inJectTypeName)
                            {
                                case "ITransentInject":
                                    service.AddTransient(item, objType);
                                    break;
                                case "IScopeInject":
                                    service.AddScoped(item, objType);
                                    break;
                                case "ISingleTonInject":
                                    service.AddSingleton(item, objType);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
            }
        }
    }

    /// <summary>
    /// 请求中获取服务依赖
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    public static TEntity GetRequestService<TEntity>(this HttpContext httpContext) where TEntity : class
    {
        return httpContext.RequestServices.GetService(typeof(TEntity)) as TEntity;
    }
}

在Startup类中的ConfigureServices方法中把服务添加到依赖并保存:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {

    }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

    // 添加服务依赖
    services.AddServices();
    // 创建一个服务依赖容器进行保存
    IocProvider.Instance = services.BuildServiceProvider();
}

然后在逻辑层中的接口中实现对应的服务依赖接口:

public interface ISysUserApp : ITransentInject
{
    #region 用户登录
    /// <summary>
    /// 用户登录
    /// </summary>
    /// <param name="account"></param>
    /// <param name="pwd"></param>
    /// <param name="loginIp"></param>
    /// <returns></returns>
    Tuple<OperatorModel, string> CheckLogin(string account, string pwd, string loginIp);
    #endregion
}

然后通过构造函数调用相应服务即可:

public class AdminLoginController : Controller
{
    private readonly ISysUserApp _sysUserApp;
    public AdminLoginController(ISysUserApp sysUserApp)
    {
        _sysUserApp = sysUserApp;
    }

    #region 后台登录
    [HttpPost]
    public IActionResult CheckLogin(string username, string password, string authcode)
    {
        try
        {
            //验证登录
            var res = _sysUserApp.CheckLogin(username, password, HttpContext.GetRequestIp());
            if (res.Item1 == null)
            {
                return Content(new AjaxResult { status = false, message = res.Item2 }.ToJson());
            }
            //保存登录信息
            OperatorProvider.Provider.AddCurrent(res.Item1);
            LogHelper.Factory.Info("登录成功");
            return Content(new AjaxResult { status = true, message = res.Item2 }.ToJson());
        }
        catch (Exception ex)
        {
            return Content(new AjaxResult { status = false, message = ex.Message }.ToJson());
        }
    }
    #endregion
}

关于服务依赖到这里就算完成了。

版权声明:若无特殊注明,本文为《奕独客》原创,转载请保留文章出处。
本文链接:.netCore3.0学习系列(二) -- Ioc容器服务依赖注入 [https://www.yiduk.com/Core学习/16.html]
正文到此结束

热门推荐