自动注册模块 插件式开发

在开发过程中各个,各个模块需要分开来开发,开发完成后最后合并将这些模块的信息存入到数据库中。在这个时候就需要在程序开始的时候需要加载这些模块信息。具体的实现方法就是通过过反射的方式获取这些模块的信息。
准备工作:
1.我在这个项目中做了一个接口IAppPlugIn
string PlugInId { get; }
string PlugInName { get; }
string RouteName { get; }
string GetUrl(string routes,string controller)//这个方法暂时不用
2.在项目中添加Areas的一个文件夹用来村放各个模块
例如:文件管理模块 会有一个FileManageAreaRegistration.cs的文件在这里插入图片描述
在这个文件里面继承IAppPlugIn 并完善模块信息
在这里插入图片描述
这些模块都是一些实现功能的父节点,下面还有一些子功能
3.模块的子功能
3-1.首先新建一个特性 里面主要用来标识子功能
在这里插入图片描述
ParentModuleId就是上面的那个模块的PlugInId
下面的属性就是存储子功能的信息
3-2:子功能的实现 就是一个控制器
在这里插入图片描述
存入相应的信息 。首先说明一些这里的控制器全部继承自一个叫HandlerLoginInfoController的控制器,他是这些控制器的BaseController,然后有这个控制器再继承Controller,因为每个控制器都有Index detail等方法所以就将其封装起来。

准备工作到此结束。

使用反射来加载这些模块
在全局文件中的Application_Start()方法中实现:
首先使用常规的反射:

 //    //Dll文件所在的文件夹
            //    string dllFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin");
            //    //加载文件路径下的dll文件
            //    string[] dllFiles = Directory.GetFiles(dllFilePath, "*.dll");
            //    //找到Z2开头的dll文件
            //    foreach (string item in dllFiles)
            //    {
            //        //获取到Z2.Web
            //        if (Path.GetFileName(item).StartsWith("Z2"))
            //        {
            //            //加载程序集
            //            Assembly ass = Assembly.LoadFile(item);
            //            //获取所有的类
            //            Type[] types = ass.GetExportedTypes();

            //            foreach (Type tt in types)
            //            {
            //                //找到所有继承字AreaRegistration的子类
            //                if (tt.IsSubclassOf(typeof(AreaRegistration)) && !tt.IsAbstract)
            //                {
            //                    //初始化对象
            //                    object obj = Activator.CreateInstance(tt);
            //                    //根节点的文件夹(Area)名称
            //                    string rootAreaName = tt.GetProperty("AreaName").GetValue(obj, null).ToString();
            //                    //根节点Id
            //                    string rootId = tt.GetProperty("PlugInId").GetValue(obj, null).ToString();
            //                    //根节点的名称
            //                    string rootName = tt.GetProperty("PlugInName").GetValue(obj, null).ToString();
            //                    //根节点添加到数据库中
            //                    Operate(rootId, "0", rootName);

            //                    //功能模块类所在的命名空间
            //                    string namesp = tt.Namespace + ".Controllers";
            //                    //加载某个节点下的模块
            //                    Assembly allClass = Assembly.GetExecutingAssembly();
            //                    //遍历每个类型
            //                    foreach (Type cla in allClass.GetTypes())
            //                    {
            //                        if (cla.Namespace == namesp)
            //                        {
            //                            string mid = string.Empty;
            //                            string mName = string.Empty;
            //                            //找具有相应特性标签的类  获取相应的特性值
            //                            ModuleActionAttribute moduleAttr = cla.GetCustomAttribute(typeof(ModuleActionAttribute)) as ModuleActionAttribute;
            //                            if (moduleAttr != null)
            //                            {
            //                                mid = moduleAttr.ModuleId;
            //                                mName = moduleAttr.ModuleName;
            //                                //将注册的模块添加到数据库中
            //                                //1.先判断是否已经存在在数据库中
            //                                Operate(mid, rootId, mName);

            //                            }//end if
            //                            else
            //                                continue;

            //                        }//end  if
            //                    }//end  foreach

            //                }//end if

            //            }//end foreach

            //        }//end if 

            //    }//end foreach

这种方法太过繁杂,不建议,效率差。
使用Linq的方式:

 //所有实现IAppPlugIn的所有类
            var allCompleteCla = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IAppPlugin))))
                .ToArray();
            //遍历所有的实现类
            foreach (var item in allCompleteCla)
            {
                var obj = Activator.CreateInstance(item) as IAppPlugin;
                if (obj == null) continue;
                var rootId = obj.PlugInId;//模块Id
                var rootName = obj.PlugInName;//模块名称
                var routeName = obj.RouteName;  //路由名
                string namesp = item.Namespace + ".Controllers";
                Operate(rootId, "0", rootName, "");
                //加载所有继承自HandlerLoginInfoController的Controllers  
                var allControllers = AppDomain.CurrentDomain.GetAssemblies()
                      .SelectMany(a => a.GetTypes().Where(t => t.IsSubclassOf(typeof(Controller))))
                      .ToArray();
                //遍历每个控制器类
                foreach (var cla in allControllers)
                {
                    if (cla.Namespace != namesp) continue;
                    var moduleAttr = cla.GetCustomAttribute(typeof(ModuleActionAttribute)) as ModuleActionAttribute;
                    if (moduleAttr != null)
                    {
                        var mId = moduleAttr.ModuleId;
                        var mName = moduleAttr.ModuleName;
                        //拼接链接路径 
                        var controller = cla.Name.Substring(0, cla.Name.Length - 10);//只获取Controller前面的部分
                        var url = RouteTable.Routes[routeName] as Route;
                        var urlAddress = obj.GetUrl(url.Url.Split('/')[0], controller);

                        //将注册的模块添加到数据库中
                        Operate(mId, rootId, mName, urlAddress);

                    }//end if
                    else
                        continue;
                }//end  foreach
            }//end  foreach

方法还有待优化。
**

**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

急景流年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值