简体   繁体   中英

How can I dynamically call a method using Namespace.Class in C#?

I have an event like this:

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;
}

I want this line to be dynamic:

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

where PrimaryKeyChecker is a namespace and another PrimaryKeyChecker is the class.

But I want to create other namespaces and classes, so is there any way to call them dynamically and load them in the combobox like this.

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

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

You've almost answered your own question! Assuming you have a list of plugins, configured in a config file or whatnot, then your PluginManager can load up the Types from the assembly using code similar to:

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

If you do not have a list of plugins, then you can either scan a directory and do the same thing as above. You could also consider using a plugin framework architecture like MEF and it does a lot of that work for you and discovers the assemblies and plugins at runtime.

I think the answer of Tom can help you populate a list of plugins. Bind them to the combobox where you put the text / description to the Type name and bind the value of combo-items to the actual Type declaration. And you asked for the event to be "Dynamic"...Do you probably mean generic??? Then i would advice to refactor the code in the click_event to a private method, to be able to call it from other "places" as well. Then in the click_event you retrieve the selected Plugin Type from the currently selected item a provide this in the generic function call to RunAnalysis like this:

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;  
        }

Another way could be to just use a parameter for the Type currently selected. Hope this helps you out or to bring you to new ideas towards a solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM