6

Voglio usare Ninject nella mia applicazione Windows e voglio sapere se ci sono buone pratiche che posso fare; strategie per trovare un equilibrio tra prestazioni e manutenzione.Ninject with Windows Application

Il problema con l'applicazione Windows e l'applicazione Web è che nell'applicazione Web esiste un ambito facile da definire che è il contesto ma con l'applicazione Windows, non esiste un ambito che sia facile da usare modulo dopo modulo.

Ad esempio, ho un servizio che interroga il database. Questo servizio ha un costruttore e ha ricevuto un UnitOfWork. Con Ninject, posso creare una proprietà contrassegnata come da iniettare, ma se lo faccio, ogni volta che creerò questo servizio, verrà creata una nuova connessione al database.

Proprio per questo motivo, devo creare manualmente i miei servizi per controllare il numero di connessione creata e non è possibile utilizzare alcun injector di dipendenza.

Ho scoperto che è possibile chiamare il metodo Inject dopo aver creato il servizio per inject dependencies ma sono sicuro di poter utilizzare una strategia migliore.

risposta

5

Con Ninject, è possibile avere una durata dell'ambito di Ninject delle dipendenze iniettate su qualsiasi oggetto che si desidera fornire (non solo ambiti Singleton, Request, Thread e Transient).

Dal Ninject Documentation Wiki:

È inoltre possibile definire facilmente si possiede scopi utilizzando l'.InScope (oggetto o) metodo.

Troverai alcuni dettagli reali su come funziona lo scoping degli oggetti in this Ninject Google Groups question & answer.

+2

+1 e relativo link http://kohari.org/2009/03/06/cache-and-collect-lifecycle-management-in-ninject-20/ è una lettura obbligata per comprendere gli obiettivi di Ninject 2.0 –

+0

Dopo aver letto gli articoli collegati, ora capisco meglio come posso controllare la durata degli oggetti dipendenti iniettati. Questo è buono ma senza una grande architettura, può essere difficile da mantenere. Sembra che pochissime persone sul web diano trucchi su come progettare una buona applicazione Windows e su come avviare l'ambito dell'oggetto in Winform tenendo sempre presente che molte altre forme possono funzionare insieme. Uso LightSpeed ​​di Mindscape e UnitOfWork utilizza la cache e quando si hanno molte winform che funzionano insieme, i dati devono spesso essere condivisi. Qualsiasi corpo ha un campione concreto di progetto? – Samuel

+0

@ Samuel, Per essere onesti, non ho visto molto in termini di applicazioni di esempio concrete che mostrano Windows Form con ORM e UnitOfWork utilizzati in un'applicazione ben progettata. Certamente mi piacerebbe vederli da solo se potessi mai trovarne. –

2

This article by Ayende in MSDN Magazine è apparentemente su NHibernate, e cita la parola inietta una sola volta (e solo in AOP), ma il fraseggio della tua domanda mi suggerisce che sarà un ottimo spunto di riflessione quando considererai come progettare la tua app .

0

È inoltre possibile rendere i framework dipendenti da un'istanza di fabbrica e affidarsi alla fabbrica per eseguire il pool di connessioni.

In alternativa, è possibile utilizzare Ninject stesso per utilizzare sempre la stessa istanza di oggetto per il tipo particolare.

3

Finalmente ho trovato quello che cercavo.

creare una classe che eredita da 'Ninject.Activation.Provider (T)'

Overrrides la funzione 'CreateInstance'

Bind l'interfaccia con quella 'Bind (di [L'interfaccia]). ToProvider ([Your provider class]) '

E ora, sarete in grado di controllare ogni istanza creata associata all'interfaccia specificata.

Si noti che è possibile passare un tipo o un'istanza al parametro provider del metodo Bind. È possibile con un'istanza creare un provider prima di collegare le interfacce e utilizzare questo provider nel codice quando si desidera creare una nuova istanza.

Il provider in combinazione con InScope consente una grande flessibilità per ogni luogo in cui si desidera avere e istanza di un oggetto che può essere iniettato automaticamente e con un ambito determinato.

Ecco un esempio:

Public Interface IConnection 

End Interface 

Public Class Connection 
    Implements IConnection 

End Class 

Imports Ninject 

Public Class StandardModule 
    Inherits Ninject.Modules.NinjectModule 

    Public Property ConnectionProvider As ConnectionProvider 

    Public Overrides Sub Load() 
     Bind(Of IConnection).ToProvider(Me.ConnectionProvider) 
    End Sub 
End Class 

Public Class ConnectionProvider 
    Inherits Ninject.Activation.Provider(Of IConnection) 

    Public Property Connection As IConnection 

    Protected Overrides Function CreateInstance(ByVal context As Ninject.Activation.IContext) As IConnection 
     Return Me.Connection 
    End Function 
End Class 

Imports Ninject 

Module EntryPoint 
    Sub Main() 
     Dim provider As New ConnectionProvider 
     Dim standardModule As New StandardModule 
     Dim connection As IConnection 
     Dim kernel As New Ninject.StandardKernel() 

     standardModule.ConnectionProvider = provider 

     kernel = New Ninject.StandardKernel(standardModule) 

     ' Here you should use a factory instead of create an instance directly but 
     ' for demonstration, it show how an instance can be propagated to object created 
     ' by NInject. 
     provider.Connection = New Connection 

     connection = kernel.Get(Of IConnection)() 
    End Sub 
End Module 
+0

Buono a sentire che senti di avere una risposta. Finché disponi di metodi lambda completi (incompleto in VB fino alla ver X (2010?), Uno in genere utilizza Bind.ToMethod() - se in realtà hai qualcosa di abbastanza complesso da richiedere una classe, in genere dovresti farlo come contenitore cosa -agnostica come parte della tua logica di dominio.Ma sicuramente ha un posto a posto, specialmente se non hai un lambda corretto. –