从 dll 程序集中获取方法和属性
Get methods and attributes from dll assembly
我正在尝试通过反映提供我的 class Plugin
的 dll 文件来获得一个小的插件机制 运行(实现我的 Plugin
-在 dll 之间共享的接口和主要项目/抱歉命名相同)提供类型 string
的属性和主要方法 activate
:
接口:
public interface Plugin
{
string pluginName{get;set;}
void activate(System.Windows.Forms.Form main);
}
dll class:
public class Plugin : WhiteA.Plugin
{
public string pluginName{get;set;}
public void activate(System.Windows.Forms.Form main){
//find the right form to modify it
IEnumerable<System.Windows.Forms.ComboBox> ie= GetControlsOfType<System.Windows.Forms.ComboBox>(main);
System.Windows.Forms.ComboBox cb=GetControlsOfType<System.Windows.Forms.ComboBox>(main).FirstOrDefault();
cb.Items.Add("Modification");
System.Windows.Forms.MessageBox.Show(cb.SelectedItem.ToString());
}
public static IEnumerable<T> GetControlsOfType<T>(System.Windows.Forms.Control root)
where T : System.Windows.Forms.Control
{
var t = root as T;
if (t != null)
yield return t;
var container = root as System.Windows.Forms.ContainerControl;
if (container != null)
foreach (System.Windows.Forms.Control c in container.Controls)
foreach (var i in GetControlsOfType<T>(c))
yield return i;
}
}
那么问题来了,程序集中找不到名为"Plugin"
的type
。试图从目录中的所有程序集中获取所有类型,从中获取所有 methods/members/custom 属性,记录它们等,但是没有找到我的 class Plugin
,而肯定会找到 dll,因为它没有 return MessageBox
。
string[] files=new string[]{};
string path="Error retrieving path";
try{
path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
files = System.IO.Directory.GetFiles(path, "*.dll");
}catch(Exception exF){
}
if(files.Length>0){
foreach (string dll in files){
try{
System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
Type myType = sampleAssembly.GetType("Plugin");
System.Reflection.MethodInfo method = myType.GetMethod("activate");
object myInstance = Activator.CreateInstance(myType);
method.Invoke(myInstance, new object[]{this});
}catch(Exception exL){
}
}
}else{
MessageBox.Show("No working plugins detected in " + path.ToString(), "Nothing to activate", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
}
我知道我的代码在你们看来可能真的很乱 - 我认为最后一个 try
块是这里唯一相关的东西,想放入 class 本身和接口虽然有点透明 - 而且我的英语并不完美,但我希望有人能帮助我在程序集中找到我的属性+方法。
编辑:
try{
System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
List<Type> list= sampleAssembly.GetTypes().Where(p =>
p.Namespace == dll &&
p.Name.Contains("Plugin")
).ToList();
Type myType=list.FirstOrDefault();
//Type myType = sampleAssembly.GetType("Plugin");
System.Reflection.MethodInfo method = myType.GetMethod("activate");
object myInstance = Activator.CreateInstance(myType);
method.Invoke(myInstance, new object[]{this});
}
我是按照Getting all types in a namespace via reflection改的
还是一样的结果,我做错了什么?
正如@stuartd指出的那样:
Type myType = sampleAssembly.GetType("WhiteA_Plugin_PausedVideo.Plugin");
是解决方案,错过了命名空间
cb.Items.Add("Modification");
虽然不起作用...有什么建议吗?
成功了直接通过控件["nameOfChild"]获取表单的子项,通过class获取所有对象的帮助方法似乎是这里错了。
插件现在可以使用了,谢谢!
我正在尝试通过反映提供我的 class Plugin
的 dll 文件来获得一个小的插件机制 运行(实现我的 Plugin
-在 dll 之间共享的接口和主要项目/抱歉命名相同)提供类型 string
的属性和主要方法 activate
:
接口:
public interface Plugin
{
string pluginName{get;set;}
void activate(System.Windows.Forms.Form main);
}
dll class:
public class Plugin : WhiteA.Plugin
{
public string pluginName{get;set;}
public void activate(System.Windows.Forms.Form main){
//find the right form to modify it
IEnumerable<System.Windows.Forms.ComboBox> ie= GetControlsOfType<System.Windows.Forms.ComboBox>(main);
System.Windows.Forms.ComboBox cb=GetControlsOfType<System.Windows.Forms.ComboBox>(main).FirstOrDefault();
cb.Items.Add("Modification");
System.Windows.Forms.MessageBox.Show(cb.SelectedItem.ToString());
}
public static IEnumerable<T> GetControlsOfType<T>(System.Windows.Forms.Control root)
where T : System.Windows.Forms.Control
{
var t = root as T;
if (t != null)
yield return t;
var container = root as System.Windows.Forms.ContainerControl;
if (container != null)
foreach (System.Windows.Forms.Control c in container.Controls)
foreach (var i in GetControlsOfType<T>(c))
yield return i;
}
}
那么问题来了,程序集中找不到名为"Plugin"
的type
。试图从目录中的所有程序集中获取所有类型,从中获取所有 methods/members/custom 属性,记录它们等,但是没有找到我的 class Plugin
,而肯定会找到 dll,因为它没有 return MessageBox
。
string[] files=new string[]{};
string path="Error retrieving path";
try{
path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
files = System.IO.Directory.GetFiles(path, "*.dll");
}catch(Exception exF){
}
if(files.Length>0){
foreach (string dll in files){
try{
System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
Type myType = sampleAssembly.GetType("Plugin");
System.Reflection.MethodInfo method = myType.GetMethod("activate");
object myInstance = Activator.CreateInstance(myType);
method.Invoke(myInstance, new object[]{this});
}catch(Exception exL){
}
}
}else{
MessageBox.Show("No working plugins detected in " + path.ToString(), "Nothing to activate", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
}
我知道我的代码在你们看来可能真的很乱 - 我认为最后一个 try
块是这里唯一相关的东西,想放入 class 本身和接口虽然有点透明 - 而且我的英语并不完美,但我希望有人能帮助我在程序集中找到我的属性+方法。
编辑:
try{
System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
List<Type> list= sampleAssembly.GetTypes().Where(p =>
p.Namespace == dll &&
p.Name.Contains("Plugin")
).ToList();
Type myType=list.FirstOrDefault();
//Type myType = sampleAssembly.GetType("Plugin");
System.Reflection.MethodInfo method = myType.GetMethod("activate");
object myInstance = Activator.CreateInstance(myType);
method.Invoke(myInstance, new object[]{this});
}
我是按照Getting all types in a namespace via reflection改的 还是一样的结果,我做错了什么?
正如@stuartd指出的那样:
Type myType = sampleAssembly.GetType("WhiteA_Plugin_PausedVideo.Plugin");
是解决方案,错过了命名空间
cb.Items.Add("Modification");
虽然不起作用...有什么建议吗?
成功了直接通过控件["nameOfChild"]获取表单的子项,通过class获取所有对象的帮助方法似乎是这里错了。
插件现在可以使用了,谢谢!