2010-12-12 4 views
0

J'ai un événement comme celui-ci:Comment puis-je appeler dynamiquement une méthode en utilisant Namespace.Class en C#?

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

Je veux que cette ligne soit dynamique:

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

où PrimaryKeyChecker est un espace de noms et un autre PrimaryKeyChecker est la classe.

Mais je veux créer d'autres espaces de noms et classes, donc il y a un moyen de les appeler dynamiquement et de les charger dans la liste déroulante comme ceci.

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

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

Répondre

1

Vous avez presque répondu à votre propre question! En supposant que vous avez une liste des plug-ins, configuré dans un fichier de configuration ou tout le reste, votre PluginManager peut charger les types de l'ensemble en utilisant un code similaire à:

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

Si vous ne disposez pas d'une liste des plug-ins, puis vous pouvez soit scanner un répertoire et faire la même chose que ci-dessus. Vous pouvez également envisager d'utiliser une architecture de framework de plugin comme MEF et cela fait beaucoup de travail pour vous et découvre les assemblys et les plugins à l'exécution.

+0

+1 pour MEF et ne pas réinventer la roue – Noctis

0

Je pense que la réponse de Tom peut vous aider à remplir une liste de plugins. Liez-les à la zone de liste déroulante où vous placez le texte/description dans le nom Type et liez la valeur de combo-items à la déclaration Type réelle. Et vous avez demandé que l'événement soit "Dynamique" ... Voulez-vous dire générique ??? Alors je conseillerais de refactoriser le code dans le click_event à une méthode privée, pour pouvoir l'appeler d'autres "endroits" aussi bien. Ensuite, dans le Click_Event vous récupérez le type de plug-in sélectionné de l'élément sélectionné a fournir ceci dans l'appel de fonction générique RunAnalysis comme ceci:

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

Une autre façon pourrait être d'utiliser simplement un paramètre pour le type sélectionné. J'espère que cela vous aide ou vous apporte de nouvelles idées vers une solution.

+0

correction au code; Activator.CreateInstance (T) doit être Activator.CreateInstance () et si vous définissez une contrainte sur la méthode (où T: IMFDBAnalyserPlugin) vous n'avez pas besoin du cast après CreateInstance. –

Questions connexes