- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
在公共项目中对当前目录进行分组,主要按照使用场景进行划分 。
按照上一章所描述的顺序进行1-4的划分,其中公共包为所有项目共用的代码,虽然该部分是编写期间随时进行编写的,但是按照个人习惯,喜欢将公共部分放到最上面.
该项目暂不涉及酷炫页面的展示效果,因此使用的是WIndows窗体应用程序,程序名称为: HardwareGatewayProductization 。
按照上文截出的页面进行布局和控件拖拽:
窗体的大小设置:Width:1536,Heigth:1454 。
使用Panel设置布局 。
先设置一个左右划分的布局,窗体宽度改变时左侧区域跟着改变,然后右侧再划分一个上下的,当窗体高度改变时,上册区域的高度会随之改变.
这样子,就完成了布局设置.
在panel2中拖拽TreeView,将Dock属性设置为Fill,CheckBoxes属性为true,命名为 hardwareTV 。
在panel4中拖拽一个Label,用于展示硬件的说明信息,命名为 infoLab 。
在panel3暂时不做处理,因为该处是定时任务所需的,先不操作.
添加 MainForm_Load 方法,一个是反射方法( InitDlls ),一个是获得反射后的类的方法( LoadLibrary ).
因为硬件网关项目也需要该反射方法,因此将该方法放到公共包中.
注 :在公共包中创建一个AssemblyLibraries项目,创建项目时位置中添加了一个public文件夹 。
在AssemblyLibrary中创建一个control文件夹,里面创建AssemBlyControl的类.
GetHardwareAbstracts 。
该类的作用是通过特定文件夹获取 HardwareAbstract 类的列表,对外接口名称为 GetHardwareAbstracts 。
/// <summary>
/// 通过获取的硬件路径返回硬件公共类
/// </summary>
/// <param name="pluginsDlls">硬件dll存放的路径</param>
/// <returns></returns>
public List<HardwareAbstract> GetHardwareAbstracts(string[] pluginsDlls = null)
{
List<HardwareAbstract> hardwareAbstracts = new List<HardwareAbstract>();
List<string> files = GetLoadDlls(pluginsDlls);
// 2.循环将每个dll文件都加载起来
foreach (string dllFile in files)
{
HardwareAbstract hardware = GetHardwareAbstract(dllFile);
if (hardware != null)
{
hardwareAbstracts.Add(hardware);
}
}
return hardwareAbstracts;
}
GetLoadDlls方法,该方法就是简单的获取特定目录下的所有dll文件,代码如下 。
List<string> files = new List<string>();
if (pluginsDlls != null && pluginsDlls.Length > 0) {
files.AddRange(Directory.GetFiles(pluginsDlls, "*.dll", SearchOption.AllDirectories));
}
return files;
GetHardwareAbstract为核心方法 。
// 2.1 动态加载当前循环的dll文件
Assembly assembly = Assembly.LoadFile(dllFile);
// 2.2 获取当前dll中的所有的public类型
Type[] types = null;
try
{
types = assembly.GetExportedTypes();
}
catch (Exception ex)
{
}
// 2.3 获取IEditor接口的Type
Type typeIEditor = typeof(HardwareAbstract);
// 查找继承自指定接口的第一个类
var clazz = types.FirstOrDefault(t => t.IsSubclassOf(typeof(HardwareAbstract)));
if (clazz != null)
{
if (clazz.IsClass && !clazz.IsAbstract && clazz.IsPublic)
{
// 检查是否存在无参的构造
if (clazz.GetConstructors().All(con => con.GetParameters().Length == 0))
{
HardwareAbstract hardware = Activator.CreateInstance(clazz) as HardwareAbstract;
hardware.IncludeDll = dllFile;
return hardware;
}
}
}
return null;
注 :所有的硬件类都默认有无参构造函数,且因为统一,所以约定所有的项目类都无有参构造函数。如果有,则需要删除检查无法构造函数的判断.
在GetHardwareAbstract中有异常抛出,因此需要重写异常类及异常的参数 AssemblyErrorEvent 和 AssemblyErrorEventArgs 。
AssemblyErrorEventArgs 异常抛出时的参数信息 。
public class AssemblyErrorEventArgs : EventArgs
{
/// <summary>
/// 读取的dll文件路径
/// </summary>
public string DllFile { get; internal set; }
/// <summary>
/// 类加载失败的异常信息
/// </summary>
public Exception Exception { get; internal set; }
/// <summary>
/// 位置
/// </summary>
public string Seek { get; internal set; }
}
AssemblyErrorEvent 异常类,异常类中的的参数基类为EventArgs 。
表示反射时硬件加载出现了什么问题 。
public delegate void AssemblyErrorEvent<T>(T e) where T : AssemblyErrorEventArgs;
添加反射公共项目依赖到硬件产品库项目中,并在InitDlls方法中添加如下代码:
AssemblyControl assembly = new AssemblyControl();
//获得dll中的文件信息
string[] dlls = Directory.GetFiles(assembly.PluginsFolder, "*.dll", SearchOption.AllDirectories);
// 全局变量List<HardwareAbstract>
_hardwares = assembly.GetHardwareAbstracts(dlls);
手动引用dll 。
基础部分已添加成功,但是有个问题,我们将硬件的所有dll都放到同一个文件夹中,那获取的dll文件将非常多,都要进行反射效率很慢;再者例如海康的依赖包过大,对于硬件产品库提取时依赖项也需要一并提取,因此手动添加引用.
说明 :
为什么要这么弄,主要是所有dll都在一个文件夹中,太过于臃肿,而分开的话就要约定每个硬件项目的依赖都不要进行复制,只需要将生成路径放到产品库指定的路径(硬件类型名称+"plugins")中即可.
而运行时需要的dll分两种,第一种为公共包中的dll,该dll只存放一份,所以项目共用;第二种为硬件项目使用,例如海康威视的依赖包。所以这两份需要分开存放,而第二种也需要根据硬件类型存放,便于后期提取时一并放到update.zip包中.
创建四个全局变量 。
LocalPath:当前项目所在路径 。
includeFolder:基础类引用路径,该路径存放的为公共包中的相关dll 。
runtimeFolder:硬件项目特定引用的dll,可能有些没有 。
pluginsFolder:组件自身的dll 。
public event AssemblyErrorEvent<AssemblyErrorEventArgs> ErrorEvent;
readonly string _includeFolder = "dlls;runtime";
readonly string _pluginsFolder = GlobalVar.LocalPath + "plugins";
readonly string _runtimeFolder = GlobalVar.LocalPath + "runtime";
在GetLoadDlls方法中直接简化为 。
return new List<string>(Directory.GetFiles(_pluginsFolder, "*.dll", SearchOption.AllDirectories));
此时硬件产品库的 GetHardwareAbstracts 方法就不需要传入参数了.
在 InitDlls 方法中手动添加dll的引用 。
AssemblyControl assembly = new AssemblyControl();
//引用文件夹中的dll
string _add1Folder = string.Join(";", Directory.GetDirectories(assembly.PluginsFolder)).Replace(Application.StartupPath + "\\", "");
string _add2Folder = string.Join(";", Directory.GetDirectories(assembly.RuntimeFolder)).Replace(Application.StartupPath + "\\", "");
string privatePath = string.Format("{0};{1};{2}", assembly.IncludeFolder, _add1Folder, _add2Folder);
AppDomain.CurrentDomain.AppendPrivatePath(privatePath);
//获得dll中的文件信息
_hardwares = assembly.GetHardwareAbstracts();
改变生成文件夹的构造 。
vs2022默认生成时,exe和依赖的dll都在一个文件夹中,很不清晰,特别是文件很多时,特别不清晰,而修改也很简单 。
在项目的App.config中添加配置代码,App.config全部内容如下 。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<!--xmlns是必需的特性。指定程序集绑定所需的 XML 命名空间。 使用字符串“urn: 架构-microsoft-com:asm.v1”作为值。-->
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<!--<publisherPolicy apply="yes"/>-->
<!--指定运行时是否使用发布者策略-->
<!--指定加载程序集时公共语言运行时搜索的子目录, 其中privatePath是相对于*.exe.config文件的相对路径,多个文件夹以分号分隔。-->
<probing privatePath="dlls;"/>
</assemblyBinding>
</runtime>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
</configuration>
下一章将介绍 LoadLibrary ,该方法主要是初始化TreeView控件,但要说明的却是 HardwareAbstract 的内容构造,因为展示TreeView简单,但是其他内容还要进行额外的添加.
最后此篇关于硬件管理平台-硬件产品库-反射模块的文章就讲到这里了,如果你想了解更多关于硬件管理平台-硬件产品库-反射模块的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
一、反射 1.定义 Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法(即使是私有的);对于任意一个对象,都能够调用它的任意方法和属性,那么,我
有没有办法从 JavaScript 对象内部获取所有方法(私有(private)、特权或公共(public))?这是示例对象: var Test = function() { // private m
我有一个抽象类“A”,类“B”和“C”扩展了 A。我想在运行时根据某些变量创建这些实例。如下所示: public abstract class A { public abstract int
假设我们在内存中有很多对象。每个都有一个不同的ID。如何迭代内存以找到与某些 id 进行比较的特定对象?为了通过 getattr 获取并使用它? 最佳答案 您应该维护这些对象的集合,因为它们是在类属性
假设我有这个结构和一个方法: package main import ( "fmt" "reflect" ) type MyStruct struct { } func (a *MyS
C#反射简介 反射(Reflection)是C#语言中一种非常有用的机制,它可以在运行时动态获取对象的类型信息并且进行相应的操作。 反射是一种在.NET Framework中广
概述 反射(Reflection)机制是指在运行时动态地获取类的信息以及操作类的成员(字段、方法、构造函数等)的能力。通过反射,我们可以在编译时期未知具体类型的情况下,通过运行时的动态
先来看一段魔法吧 public class Test { private static void changeStrValue(String str, char[] value) {
结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套; go中的struct类型理解为类,可以定义方法,和函数定义有些许区别; struct类型是值类型
反射 1. 反射的定义 Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们
反射的定义 java的反射(reflection) 机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到嘛,那么,我们就可以
我有一个 Java POJO: public class Event { private String id; private String name; private Lon
我编写了以下函数来检查给定的单例类是否实现了特征。 /** Given a singleton class, returns singleton object if cls implements T.
我正在研究 Java 反射的基础知识并观察有关类方法的信息。我需要获得一个符合 getMethod() 函数描述的规范的方法。然而,当我这样做时,我得到了一个 NoSuchMethodExceptio
我正在通过以下代码检索 IEnumerable 属性列表: BindingFlags bindingFlag = BindingFlags.Instance | BindingFlags.Public
我需要检查属性是否在其伙伴类中定义了特定属性: [MetadataType(typeof(Metadata))] public sealed partial class Address { p
我正在尝试使用 Reflections(由 org.reflections 提供)来处理一些繁重的工作,因此我不需要在很长的时间内为每个类手动创建一个实例列表。但是,Reflections 并未按照我
scala 反射 API (2.10) 是否提供更简单的方法来搜索加载的类并将列表过滤到实现定义特征的特定类? IE; trait Widget { def turn(): Int } class
我想在运行时使用反射来查找具有给定注释的所有类,但是我不知道如何在 Scala 中这样做。然后我想获取注释的值并动态实例化每个映射到关联注释值的带注释类的实例。 这是我想要做的: package pr
这超出了我的头脑,有人可以更好地向我解释吗? http://mathworld.wolfram.com/Reflection.html 我正在制作一个 2d 突破格斗游戏,所以我需要球能够在它击中墙壁
我是一名优秀的程序员,十分优秀!