• 实现简单的构造函数注入容器


      这段时间跟着Eleven老师学习收获不小,一些以前想过的可能,但是以前不知道怎么实现。

      今天上班领导不在,突然想起来,便试着实现了一下诸如容器,发现 基本实现还是挺简单,基本就是反射的应用了。不废话,上代码。

      首先是 容器的代码(新建一个类库封装):

      

    public class InjectContainer
        {
            private static Dictionary<string, object> dicToInstances = new Dictionary<string, object>();
                   private static Dictionary<string, List<Type>> dicReturnTypeInfo = new Dictionary<string, List<Type>>();
            private static object objLock = new object();
    
            /// <summary>
            /// 接口注册(接口类和实现类之间的约束是接口类名称为实现类名称前面加 I)
            /// </summary>
            /// <param name="fromNameSpace">接口类命名空间</param>
            /// <param name="toNameSpace">实现类命名空间</param>
            public void Register(string fromNameSpace, string toNameSpace)
            {
                var issembly = Assembly.Load(fromNameSpace);
                var toAssembly = Assembly.Load(toNameSpace);
                var types = issembly.GetTypes();
                foreach (var type in types)
                {
                    if (dicToInstances.ContainsKey(type.FullName)) continue;
                    var toType = toAssembly.GetType(string.Format("{0}.{1}", toNameSpace, type.Name.Substring(1)));
                    var instance = Activator.CreateInstance(toType);
                    dicToInstances.Add(type.FullName, instance);
                }
            }
    /// <summary>
            /// 获取实体(控制器每次访问都是要创建新实例的)
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            public T GetInstance<T>(Type type)
            {
                List<Type> listType = new List<Type>();
                if (dicReturnTypeInfo.ContainsKey(type.FullName))
                {
                    //如果有类型数据就不需要再获取一次了
                    listType = dicReturnTypeInfo[type.FullName];
                }
                else
                {
                   lock (objLock)
                        {
                            if (!dicReturnTypeInfo.ContainsKey(type.FullName))
                            {
                                var ConstructorInfo = type.GetConstructors();
                                var parameters = ConstructorInfo[0].GetParameters();
    
                                foreach (var item in parameters)
                                {
                                    Type fromType = item.ParameterType;
                                    listType.Add(fromType);
    
                                }
                            }
                        }
                    
                }
                List<object> param = new List<object>();
                foreach (var pType in listType)
                {
                    if (dicToInstances.ContainsKey(pType.FullName))
                    {
                        param.Add(dicToInstances[pType.FullName]);
                    }
                }
                return (T)Activator.CreateInstance(type, param.ToArray());
            }
    
    
        }

      然后建两个新的类库,分别为接口类库(IRepository)和接口实现类库(Repository)

    namespace IRepository
    {
        public interface IStudentManager
        {
            string GetStudentName();
            void SetStudentName(string name);
        }
    }
    namespace Repository
    {
        public class StudentManager : IStudentManager
        {
            private string _Name { get; set; }
            public string GetStudentName()
            {
                return this._Name;
            }
    
            public void SetStudentName(string name)
            {
                this._Name = "Name of the student is : "+name;
            }
        }
    }

      最后 我们建我们的 MVC 项目,这里建一个基本的 MVC 项目(项目只需引用容器类库和接口类库)。

      然后在 App_Start 文件夹里(其实在哪都可以)新建一个 自定义控制器工厂 CustomControllerFactory 继承自 DefaultControllerFactory,然后重写 GetControllerInstance 方法

    /// <summary>
        /// 自定义控制器生成类
        /// </summary>
        public class CustomControllerFactory: DefaultControllerFactory
        {
            private InjectContainer _Container = null;
            public CustomControllerFactory(InjectContainer container)
            {
                this._Container = container;
            }
            protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
            {
                if (controllerType != null)
                    return this._Container.GetInstance<IController>(controllerType);
                return null;
            }
        }

      接着在 MVC 项目的 Global.asax 文件里注册 容器

     protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                RouteConfig.RegisterRoutes(RouteTable.Routes);
    
                //以下是容器注册
                InjectContainer container = new InjectContainer();
                container.Register("IRepository", "Repository");
                ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory(container));
            }

      最后  我们在我们需要注入的 控制器 重载一个带参数的 构造函数

    public class HomeController : Controller
        {
            private IStudentManager _StudentManager = null;
            /// <summary>
            /// 带接口参数的构造函数
            /// </summary>
            /// <param name="studentManager"></param>
            public HomeController(IStudentManager studentManager)
            {
                this._StudentManager = studentManager;
            }
            // GET: Home
            public ActionResult Index()
            {
                this._StudentManager.SetStudentName("我在使用自己的注入容器,呵呵哈哈哈");
                return Content(this._StudentManager.GetStudentName());
            }
        }

      

      整个项目结构如图:

      效果:

      

  • 相关阅读:
    solr 重要的知识点
    Sole跟Tomcat的整合 Solr4.4 + Tomcat
    常用SQL总结
    T4生成实体和简单的CRUD操作
    磁盘分区
    salt一键部署zookeeper
    salt一键部署gcc-c++
    salt一键部署python
    linux目录文件权限的区别。
    salt一键部署jdk
  • 原文地址:https://www.cnblogs.com/mengtree/p/7123149.html
Copyright © 2020-2023  润新知