Ho un requisito che I penso Ho una soluzione per, ma apprezzerei l'input nel caso mi manchi qualcosa o mi metto su per fallimento lungo la strada.Late Binding e WithEvents utilizzando VBA
Il requisito
implementare alcune nuove logiche di business in una nuova libreria (utilizzando C#) che riporta indietro il suo stato attraverso gli eventi. La libreria sarà invocata da una soluzione VBA esistente (non può ancora cambiarlo). La libreria è esposta a VBA tramite COM Interop - nessun problema qui.
Oltre alla funzionalità "di base" esposta da questa nuova libreria, è necessario consentire che la funzionalità di base venga sostituita dalla funzionalità "personalizzata" lungo la strada.
Entrambe le funzionalità di base e personalizzata implementeranno la stessa interfaccia, ma i metodi privati interni di ciascuno saranno diversi per una serie di motivi.
In VBA
ho bisogno di essere in grado di richiamare sia la libreria di base o libreria personalizzata (e forse altre librerie personalizzate che implementano la stessa interfaccia in futuro). Se non fosse per il requisito di rispondere e visualizzare i messaggi dalle librerie, potrei semplicemente usare Late Binding per creare un'istanza dell'oggetto in fase di runtime. Tuttavia, poiché devo rispondere agli eventi generati dalle librerie, è necessario utilizzare la parola chiave WithEvents
quando si dichiara la variabile in VBA.
Se solo avessi per sostenere la libreria di base avrei potuto fare qualcosa di simile al seguente:
Private WithEvents Processor As MyDefault.RuleEngine
Public Sub Execute(StartDate As Date, EndDate As Date, SomeOtherParms As String)
Set Processor = New MyDefault.RuleEngine
Processor.Execute StartDate, EndDate, SomeOtherParms
End Sub
Private Sub Processor_OnProgressUpdate(ByVal percentComplete As Double)
'Show the progress on the UI to the user
End Sub
Dal momento che ho per supportare implementazioni personalizzate di questa libreria (alcuni dei quali conosco circa ora, gli altri che non conosco ancora) Vorrei come utilizzare l'associazione tardiva per gestire questo scenario.
Tuttavia, WithEvents non può essere utilizzato con Late Binding, sebbene possa essersi imbattuto in una soluzione alternativa.
Nel mio scenario, ho sempre avere un riferimento all'implementazione di base. Sarà solo in circostanze specifiche e configurate in cui la funzionalità di base verrà sostituita da un'implementazione personalizzata.
Dal momento che la libreria di base e personalizzati (i) condividono la stessa interfaccia, ho il seguente codice di lavoro in una prova di concetto:
Private WithEvents Processor As MyDefault.RuleEngine
Public Sub Execute(StartDate As Date, EndDate As Date, SomeOtherParms As String)
If CustomConditionIsMet Then
'In real-life we'll look this info up from a table or config file
Set Processor = CreateObject("MyCustom.RuleEngine")
Else
Set Processor = New MyDefault.RuleEngine
End If
Processor.Execute StartDate, EndDate, SomeOtherParms
End Sub
Private Sub Processor_OnProgressUpdate(ByVal percentComplete As Double)
'Show the progress on the UI to the user
End Sub
Questa implementazione funziona senza errori (sia in fase di compilazione e di esecuzione), ma sono un po 'titubante nell'usare questa soluzione in futuro perché non mi sento di avere una solida comprensione di come \ perché questo funzioni effettivamente. Il mio sospetto è che funzioni perché entrambe le librerie di base e personalizzate condividono la stessa interfaccia, quindi COM è "felice" con l'associazione tardiva tramite la dichiarazione CreateObject
, ma ho paura di ciò che potrei mancare qui che potenzialmente mi causerebbe dolore lungo la strada.
La mia domanda
E ' "sicuro" a fare affidamento su questa soluzione alternativa per l'associazione tardiva utilizzando WithEvents
, e se sì, perché?
In caso contrario, ci sono delle alternative che potrei cercare di implementare (oltre a non utilizzare VBA, che non ho una scelta in questo scenario)?
Non ho intenzione di fingere di conoscere la risposta, ma penserei che fintanto che entrambe le classi utilizzano la stessa interfaccia, tu stai bene. Dopo tutto, è necessario utilizzare un'interfaccia anziché un'implementazione concreta quando si utilizza COM Interop. Per quanto riguarda VBA, sono dello stesso tipo (essenzialmente). A proposito, domanda davvero interessante. – RubberDuck