Metodo per caricare ed eseguire il codice definito dall'utente nell'applicazione Windows .NET

0

Esistono schemi che descrivono come caricare e caricare l'applicazione ed eseguire il codice definito dall'utente in fase di esecuzione? Sto cercando di sviluppare una libreria C # che gli utenti di un'applicazione Test Executive (app che interagisce con HW per testare i dispositivi mobili in fase di sviluppo) possano sfruttare per definire il codice di test (attualmente i test sono definiti in xml attraverso un design piuttosto ingombrante / mal progettato Interfaccia utente e abbiamo avuto richieste per una sorta di libreria). Il codice di prova dovrà essere caricato ed eseguito dall'applicazione. L'approccio proposto è ...

  1. Distribuisci una libreria di metodi che un utente può sviluppare test con
  2. Distribuisci un piccolo framework con interfacce che dovrebbero essere implementate in modo che l'applicazione possa individuare il codice di test.
  3. L'utente compila i test nelle DLL dal progetto che fa riferimento alle DLL da 1 e 2
  4. L'applicazione carica DLL fornite dall'utente (generate nel passaggio 3) e individua il metodo di test (definito nel framework da 2) tramite la riflessione sulla DLL
  5. L'applicazione esegue il codice di prova che dovrebbe essere una serie di chiamate di metodo da 1
  6. La libreria di 1 utilizza la riflessione in modo che ogni chiamata di metodo dalle mappe della libreria ad alcune serie di chiamate definite all'interno dell'assembly dell'applicazione in esecuzione.

L'utente potrebbe scrivere qualcosa che assomiglia a questo:

using MyFramework;
using MyLib;
namespace Test
{
    public class MyTest : MyFramework.Test //defines the abstract RunTest method
    {
      public override void RunTest() { //user implements RunTest
        //the test code
        MyLib.Commands commands = new MyLib.Commands();
        commands.Command1();
        commands.Command2();
      }
    }
}

Il codice che l'utente scrive verrà compilato su una DLL e reso disponibile per l'applicazione. MyLib.Commands.Command1 farebbe questo (illustrazione del punto numero 6):

public void Command1() {
    Assembly exeAssembly = Assembly.LoadFile(@"C:\theAppThatRunsTheUserCode.exe");
    Type typeInAppWhereLibCallsMapTo = exeAssembly.GetType("app.targetType");
    MethodInfo methodMappedToLibCall = typeInAppWhereLibCallsMapTo.GetMethod("AppCommand1");
    methodMappedToLibCall.Invoke(null, null);  
}

L'applicazione eseguirà un codice utente come questo:

public void RunTheUserTest() {
    Assembly dllAssembly = Assembly.LoadFile(@"C:\Test.dll");
    Type testType = dllAssembly.GetType("Test.MyTest");
    object myTestInstance = Activator.CreateInstance(testType);
    MethodInfo runTestMethodInfo = testType.GetMethod("RunTest");
    runTestMethodInfo.Invoke(myTestInstance, null);
}

Esistono modelli di progettazione ben noti che sono più adatti a risolvere questo tipo di problema? Mi chiedo se questo è un approccio a posto. In caso contrario, cosa c'è di sbagliato in questo? Ci sono modi più semplici / "più eleganti" per risolvere questo tipo di problema?

    
posta Doug Tait 01.08.2018 - 00:05
fonte

1 risposta

1

Il Managed Extensibility Framework (MEF) può gestire il cablaggio delle classi da .dll file caricati al runtime in base a una definizione di interfaccia condivisa.

In pratica, dichiari una dipendenza aggiungendo [Import] . Questa dipendenza verrà soddisfatta con tutto ciò che può essere trovato nei file .dll caricati che ha una corrispondenza [Export] attributo.

    
risposta data 01.08.2018 - 01:25
fonte

Leggi altre domande sui tag