如何在C#中使用Namespace.Class动态调用方法?

时间:2010-12-12 08:04:29

标签: c# .net winforms methods

我有这样的事件:

private void btnStartAnalysis_Click(object sender, EventArgs e)
{
    SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder();
    objConnectionString.DataSource = txtHost.Text;
    objConnectionString.UserID = txtUsername.Text;
    objConnectionString.Password = txtPassword.Text;
    objConnectionString.InitialCatalog = Convert.ToString(cmbDatabases.SelectedValue);
    string[] arrArgs = { objConnectionString.ConnectionString };

    //Checks for the selectedItem in the cmbOpearions dropdown and make call to appropriate functions.
    string assemblyName = cmbOperations.SelectedValue.ToString();
    Assembly assembly = Assembly.LoadFrom(assemblyName);
    Type localType = assembly.GetType("PrimaryKeyChecker.PrimaryKeyChecker");

    IMFDBAnalyserPlugin analyser = (IMFDBAnalyserPlugin) Activator.CreateInstance(localType);
    string response = analyser.RunAnalysis(objConnectionString.ConnectionString);

    //show the response of the the function call
    txtPluginResponse.Text = response;
}

我希望这一行是动态的:

Type localType = assembly.GetType("PrimaryKeyChecker.PrimaryKeyChecker");

其中PrimaryKeyChecker是一个名称空间,另一个PrimaryKeyChecker是该类。

但我想创建其他名称空间和类,所以有没有办法动态调用它们并将它们加载到这样的组合框中。

public void SetOperationDropDown()
{
    cmbOperations.DataSource = PluginManager.GetAllPlugins();

    if(cmbOperations.Items.Count > 0)
    {
        cmbOperations.SelectedItem = cmbOperations.Items[0];
    }
}

2 个答案:

答案 0 :(得分:1)

你差不多回答了自己的问题!假设你有一个插件列表,在配置文件或诸如此类的东西中配置,那么你的插件管理器可以使用类似于的代码从程序集中加载类型:

Type analyserType = typeof(IMFDBAnalyserPlugin);
foreach(Type t in assembly.GetTypes()) {
    if(t.IsSubtypeOf(analyserType) {
        plugins.Add((IMFDBAnalyserPlugin) Activator.CreateInstance(t));
    }
}

如果您没有插件列表,那么您可以扫描目录并执行与上面相同的操作。您还可以考虑使用像MEF这样的插件框架体系结构,它可以为您完成大量工作,并在运行时发现程序集和插件。

答案 1 :(得分:0)

我认为Tom的答案可以帮助您填充插件列表。将它们绑定到组合框,在其中将文本/描述放入类型名称,并将组合项的值绑定到实际的类型声明。你要求这个活动是“动态的”...你可能是指通用???然后我建议将click_event中的代码重构为私有方法,以便能够从其他“位置”调用它。然后在click_event中从当前选择的项中检索所选的插件类型,在通用函数调用RunInnalysis中提供这个,如下所示:

private void btnStartAnalysis_Click(object sender, EventArgs e)
{
    if(cmbOperations.SelectedItem != null)
        RunAnalysis<cmbOperations.SelectedItem.Value>();  
}

    private void RunAnalysis<T>()
    {
            //Checks for the selectedItem in the cmbOpearions dropdown and make call to appropriate functions.  
            //string assemblyName = cmbOperations.SelectedValue.ToString();  
            //Assembly assembly = Assembly.LoadFrom(assemblyName);  

            //Type localType = assembly.GetType("PrimaryKeyChecker.PrimaryKeyChecker");  

                IMFDBAnalyserPlugin analyser = 
                  (IMFDBAnalyserPlugin) Activator.CreateInstance(T);  

string response = analyser.RunAnalysis(objConnectionString.ConnectionString);  

                //show the response of the the function call  
            txtPluginResponse.Text = response;  
        }

另一种方法是只为当前选择的Type使用参数。希望这可以帮助您或者为您带来解决方案的新想法。