我想通過反射一個dll文件來提供我的類運行的小插件機制Plugin
(實現我的Plugin
-在dll和主要項目之間共享的接口/抱歉命名都相同)提供string
類型的activate
的屬性和主方法:從dll程序集中獲取方法和屬性
接口:
public interface Plugin
{
string pluginName{get;set;}
void activate(System.Windows.Forms.Form main);
}
DLL類:
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;
}
}
因此出現這個問題,在程序集中找不到type
,名稱爲"Plugin"
。試圖從目錄中的所有程序集中獲取所有類型,從它們獲取所有方法/成員/自定義屬性,讓它們登錄等等,但是找不到我的類Plugin
,而dll肯定被找到,因爲它不返回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
- 塊是唯一與此有關,希望把在類本身和接口一點點的透明度,但 - 而我的英文不是很完美,但我希望有人能幫助我在程序集中找到我的屬性+方法。
編輯:
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 還是一樣的結果改變它,我做了什麼錯?
我想你需要將命名空間傳遞給'GetType()'?比如'sampleAssembly.GetType(「MyApp.Plugins.Plugin」);'?請注意,您不會傳遞_assembly_名稱 - 請參閱[文檔](https://msdn.microsoft.com/en-us/library/y0cd10tb(v = vs.110).aspx) – stuartd
此處已回答此問題。 https://stackoverflow.com/questions/79693/getting-all-types-in-a-namespace-via-reflection/34869091#34869091 –
@stuartd這意味着我的所有插件都需要有相同的命名空間,對吧?這是必要/允許的嗎? – Kartoffel