2009-05-24 13 views
5

Scrivo alcune librerie di classi C# e voglio utilizzare Ninject per fornire l'iniezione di dipendenza per le mie classi. È possibile che la liberia di classe dichiari un codice (metodo) che dovrebbe essere eseguito ogni volta che viene caricata la liberia della classe. Ho bisogno di questo per definire i collegamenti per Ninject.Metodo C# che viene eseguito dopo il caricamento dell'assieme

risposta

1

Ho usato Ninject un po 'negli ultimi 9 mesi. Sembra che quello che devi fare è "caricare" i tuoi moduli che esistono nel tuo libray nel kernel di Ninject per registrare i binding.

Non sono sicuro che si utilizzi Ninject 1.x o 2.0 beta. Le due versioni eseguono le cose in modo leggermente diverso, anche se concettualmente sono uguali. Continuerò con la versione 1.x per questa discussione. L'altra informazione che non conosco è se il tuo programma principale sta creando un'istanza del kernel di Ninject e la tua libreria sta semplicemente aggiungendo collegamenti a quel kernel, o se la tua libreria contiene il kernel e le associazioni. Presumo che sia necessario aggiungere collegamenti nella libreria a un kernel Ninject esistente nell'assembly principale. Infine, supporrò che tu stia caricando dinamicamente questa libreria e che non sia collegata staticamente al programma principale.

La prima cosa da fare è definire un modulo ninject nella libreria in cui si registrano tutti i binding. È possibile che lo si sia già fatto, ma vale la pena menzionarlo.Per esempio:

public class MyLibraryModule : StandardModule { 
    public override void Load() { 
    Bind<IMyService>() 
     .To<ServiceImpl>(); 
    // ... more bindings ... 
    } 
} 

Ora che le associazioni sono contenuti all'interno di un modulo Ninject, si può facilmente registrarli quando si carica l'assembly. L'idea è che una volta caricato il tuo assieme, puoi scansionarlo per tutti i tipi derivati ​​da StandardModule. Una volta che hai questi tipi, puoi caricarli nel kernel.

Una cosa da notare, è possibile generalizzare ulteriormente il codice sopra per caricare più librerie e registrare più tipi. Inoltre, come ho già detto, Ninject 2 ha questo tipo di funzionalità integrate, che in realtà ha la capacità di scansionare directory, caricare assiemi e moduli di registro. Molto bello

Se lo scenario è leggermente diverso da quello che ho delineato, è probabile che i principi simili vengano adattati.

6

Sembra che si stia cercando l'equivalente del DllMain di C++. Non c'è modo di farlo in C#.

Puoi fornirci ulteriori informazioni sul tuo scenario e perché hai bisogno di codice da eseguire in una funzione di stile DllMain?

La definizione di un costruttore statico su un tipo non risolve questo problema. Un costruttore di tipi statici può funzionare solo prima che il tipo stesso venga utilizzato in qualsiasi modo. È possibile definire un costruttore statico, utilizzare un altro codice all'interno della DLL che non accede al tipo e il costruttore non verrà mai eseguito.

-1

Per quanto ne so la risposta è no . Come ho capito, si desidera configurare il proprio contenitore IoC nella libreria di classi e se è il caso, non è una buona idea farlo. Se si definiscono i binding nel libreria di classe quindi a che cosa serve l'iniezione delle dipendenze? usiamo l'iniezione di dipendenza in modo che possiamo iniettare dipendenze in fase di esecuzione, quindi possiamo iniettare oggetti diversi in scenari diversi. Anche se il posto migliore per configurare un contenitore IoC è l'avvio dell'applicazione (poiché un contenitore IoC è come una dorsale per un'applicazione :)) ma dovrebbe essere posizionato in un bootstrap responsabile per l'avvio dell'applicazione. Nelle applicazioni semplici può essere il metodo Main.

+0

Ci sono molte situazioni in cui si desidera definire i binding in una libreria di classi. Potresti potenzialmente avere implementazioni diverse dello stesso servizio in diverse librerie, entrambe possono essere pertinenti nella stessa applicazione allo stesso tempo in base al contesto in cui viene utilizzato il servizio. Ninject (come altri IoC) offre la possibilità di definire i binding contestuali, avendo così la possibilità di attivare diversi servizi concreti basati su un contesto fornito. –

0

È possibile controllare il codice cliente? Se sì, invece di provare a fare magie durante il caricamento di assembly, vorrei implementare una singola classe come Registry che esegue i bind, implementando un'interfaccia IRegistry. Quindi durante il caricamento è possibile cercare l'implementazione di IRegistry nel proprio assieme e attivare i metodi necessari.

Si può anche avere attributi sulle classi:

[Component(Implements=typeof(IMyDependency)] 

look per questi attributi e caricarli al contenitore sul lato client.

Oppure è possibile dare un'occhiata a MEF che è una libreria per questo tipo di situazioni.

1

Hai provato l'evento AppDomain.AssemblyLoad? Spara dopo che un assieme è stato caricato.

AppDomain.CurrentDomain.AssemblyLoad += (s, e) => 
{ 
    Assembly justLoaded = e.LoadedAssembly; 
    // ... etc. 
}; 
Problemi correlati