Domanda

Scrivo alcune librerie di classi C# e voglio utilizzare Ninject per fornire l'inserimento di dipendenze per le mie classi.È possibile che la libreria di classi dichiari del codice (metodo) che verrà eseguito ogni volta che viene caricata la libreria di classi.Ne ho bisogno per definire i collegamenti per Ninject.

È stato utile?

Soluzione

Ho usato Ninject parecchio negli ultimi 9 mesi.Sembra che quello che devi fare sia "caricare" i tuoi moduli che esistono nella tua libreria nel kernel Ninject per registrare i collegamenti.

Non sono sicuro se stai utilizzando Ninject 1.x o la versione beta 2.0.Le due versioni eseguono le cose in modo leggermente diverso, anche se concettualmente sono le stesse.Continuerò con la versione 1.x per questa discussione.L'altra informazione che non so è se il tuo programma principale sta istanziando il kernel Ninject e la tua libreria sta semplicemente aggiungendo collegamenti a quel kernel, o se la tua libreria stessa contiene il kernel e i collegamenti.Presumo che sia necessario aggiungere collegamenti nella libreria a un kernel Ninject esistente nell'assembly principale.Infine, presumo 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 tua libreria in cui registri tutti i tuoi collegamenti: potresti averlo 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 i tuoi collegamenti sono contenuti all'interno di un modulo Ninject, puoi registrarli facilmente durante il caricamento dell'assembly.L'idea è che una volta caricato l'assembly, è possibile scansionarlo per tutti i tipi derivati ​​da StandardModule.Una volta che hai questi tipi, puoi caricarli nel kernel.

// Somewhere, you define the kernel...
var kernel = new StandardKernel();

// ... then elsewhere, load your library and load the modules in it ...

var myLib = Assembly.Load("MyLibrary");
var stdModuleTypes = myLib
                       .GetExportedTypes()
                       .Where(t => typeof(StandardModule).IsAssignableFrom(t));


foreach (Type type in stdModuleTypes) {
  kernel.Load((StandardModule)Activator.CreateInstance(type));
}

Una cosa da notare è che puoi generalizzare ulteriormente il codice precedente per caricare più librerie e registrare più tipi.Inoltre, come ho già detto, Ninject 2 ha questo tipo di funzionalità integrata: ha effettivamente la capacità di scansionare directory, caricare assembly e registrare moduli.Molto bello.

Se il tuo scenario è leggermente diverso da quello che ho delineato, probabilmente è possibile adattare principi simili.

Altri suggerimenti

Sembra che si sta cercando l'equivalente di DllMain C ++ 's. Non c'è modo per fare questo in C #.

Può darci qualche informazione in più lo scenario e perché è necessario il codice da eseguire in una funzione DllMain stile?

La definizione di un costruttore statico su un tipo non risolve questo problema. Un tipo costruttore statico è garantita solo per eseguire prima del tipo stesso viene utilizzato in alcun modo. È possibile definire un costruttore statico, utilizzare altro codice all'interno della DLL che non accedere al tipo ed è il costruttore non potrà mai funzionare.

Hai provato l'evento AppDomain.AssemblyLoad? Si spara dopo che un assembly è stato caricato.

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

Si può controllare il codice del client? Se sì, invece di cercare di fare magie durante il caricamento di montaggio, vorrei andare per l'implementazione di una singola classe, come del Registro di sistema che fa le associazioni, l'implementazione di un IRegistry interfaccia. Poi durante il caricamento si può guardare per l'attuazione del IRegistry nei vostri assemblaggio e fuoco metodi necessari.

Si può anche avere gli attributi per le vostre classi:

[Component(Implements=typeof(IMyDependency)]

cercare questi attributi e caricarli al contenitore sul lato client.

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

Per quanto ne so la risposta è no .Come ho capito che si desidera configurare il contenitore CIO nella vostra libreria di classi e Se questo è il caso non è una buona idea per fare that.If si definiscono le associazioni nella vostra libreria di classi allora che cosa è l'uso di iniezione di dipendenza? usiamo l'iniezione di dipendenza in modo che possiamo iniettare le dipendenze in fase di runtime, allora siamo in grado di iniettare diversi oggetti in diversi scenarios.Although il posto migliore per configurare un contenitore CIO è l'avvio della vostra applicazione (in quanto un contenitore CIO è come una spina dorsale per un'applicazione :)) ma dovrebbe essere posizionato ad una bootstrap che è responsabile per avviare i semplici applicazioni application.In può essere il metodo principale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top