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.G开发者_Go百科etAllPlugins();
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.
精彩评论