欢迎访问个人博客站点: 配置啦

关于asp.net mvc的控制器的依赖注入思考及对StructureMap依赖注入框架的简单实践笔记

写在前面

依赖注入这个玩意很多人其实都接触过,但可能没有细究其中的原理。

                  比如Controller的构造函数中,只要你传入一些接口,应用自动就给你处理了创建的过程,无需你手动去new 一个实例并穿进去来创建Controller.

                  比如:

    public class LoginController : BaseController
    {

        public LoginController(IOptions<AppSet> option) : base(option)
        {

        }
    }

       或者

    public class APIController : ControllerBase
    {
        private readonly IHttpContextAccessor httpContextAccessor;

        // GET api/values
        public APIController(IHttpContextAccessor httpContextAccessor)
        {
            this.httpContextAccessor = httpContextAccessor;
        }
    }

技术分析

          试想,如果没有一个注入机制,我们肯定得来 new 创建对象了。new不但类,而且后期还不好改,因为有100个地方则new 了100个地方,想换一个接口的实现类,就需要到处去修改了。于是有人就推出了专门解决类似问题的框架,本文介绍:StructureMap.

使用场景:(假设有验证码登录,短信验证登录...):

    public interface ILog
    {
        void Work();
    }
    public interface ILogin
    {
        void Work();
    }
    public interface IReposibility
    {
        void Work();
    }
    public interface ISmsCode
    {
        void Work();
    }
    public interface IVerifyCode
    {
        void Work();
    }

相关的实现类:

    /// <summary>
    ///  账号密码+短信的登录
    /// </summary>
    public class LoginWithSmsCode : ILogin
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="reposibility"></param>
        /// <param name="verifyCode"></param>
        public LoginWithSmsCode(IReposibility reposibility, ISmsCode smsCode)
        {
            ConfigLab.Utils.SaveLog($"LoginWithSmsCode:被创建");
        }
        public void Work()
        {
           
        }
    }

    /// <summary>
    ///  账号密码+验证码的登录
    /// </summary>
    public class LoginWithVerifyCode:ILogin
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="reposibility"></param>
        /// <param name="verifyCode"></param>
        public LoginWithVerifyCode(IReposibility reposibility,IVerifyCode verifyCode)
        {
            ConfigLab.Utils.SaveLog($"LoginWithVerifyCode:被创建");
        }
        public void Work()
        {

        }
    }
    public class SmsCode:ISmsCode
    {
        public SmsCode(IReposibility reposibility,ILog log)
        {
            ConfigLab.Utils.SaveLog($"SmsCode:被创建");
        }
        public void Work()
        {

        }
    }
    public class VerifyCode :IVerifyCode
    {
        public VerifyCode(IReposibility reposibility, ILog log)
        {
            ConfigLab.Utils.SaveLog($"VerifyCode:被创建");
        }
        public void Work()
        {

        }
    }
    public class Reposibility:IReposibility
    {
        public Reposibility()
        {
            ConfigLab.Utils.SaveLog($"Reposibility:被创建");
        }
        public void Work()
        {

        }
    }
    public class Log:ILog
    {
        public Log()
        {
            ConfigLab.Utils.SaveLog($"Log:被创建");
        }
        public void Work()
        {

        }
    }

StructureMap使用-容器初始化:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StructureMap;
using ConfigLab.LabCore.IocLab.Interfaces;
using ConfigLab.LabCore.IocLab;
using System.Runtime.CompilerServices;

namespace ConfigLab.LabCore
{
    /// <summary>
    /// 功能简介:StructureMap容器的初始化
    /// 作者:http://cnblogs.com/taohuadaozhu
    /// 备注:这里只用了一些简单的处理,还有自动扫描程序集scan等,可自行查找StructureMap的资料.
    /// </summary>
    public static class AppRunContext
    {
        private static  Container _gContainner = null;
        public static Container gContainner
        {
            get
            {
                if (_gContainner == null)
                {
                    Init();
                }
                return _gContainner;
            }
        }
        /// <summary>
        /// 功能简介:初始化(应用程序只需一次初始化),可以放到服务的初始化或者asp.net mvc中Application_Start中。
        /// </summary>
        private static void Init()
        {
            _gContainner = new Container(_=> {
                _.For<ILogin>().Use<LoginWithVerifyCode>();
                _.For<ISmsCode>().Use<SmsCode>();
                _.For<IVerifyCode>().Use<VerifyCode>();
                _.For<ILog>().Use<Log>();
                _.For<IReposibility>().Use<Reposibility>();
            });
        }
    }
}

StructureMap使用-创建接口的实现类对象:

            ILogin login= AppRunContext.gContainner.GetInstance<ILogin>();//这里每次创建无需指定是验证码还是短信验证,在初始化的时候规定了,如果修改只需修改初始化容器那块。