6

Quiero usar Ninject en mi aplicación de Windows y quiero saber si hay mejores prácticas que puedo hacer; estrategias para encontrar un equilibrio entre rendimiento y mantenimiento. El problema con la aplicación de Windows y la aplicación web es que en la aplicación web, hay un ámbito fácil de definir que es el contexto, pero con la aplicación de Windows, no tiene un ámbito fácil de usar formulario tras formulario.Ninject con la aplicación de Windows

Como ejemplo, tengo un servicio que consulta la base de datos. Este servicio tiene un constructor y recibió un UnitOfWork. Con Ninject, puedo crear una propiedad marcada para ser inyectada, pero si lo hago, cada vez que crearé este servicio, se creará una nueva conexión a la base de datos.

Por esta razón, debo crear mis servicios manualmente para controlar la cantidad de conexiones creadas y no se puede usar ningún inyector de dependencia.

He encontrado que puede llamar al método Inject después de haber creado el servicio para inyectar dependencias pero estoy seguro de que puedo usar una mejor estrategia.

Respuesta

5

Con Ninject, puede tener vidas de alcance de Ninject de sus dependencias inyectadas a cualquier objeto que desee proporcionar (no solo Singleton, solicitud, subproceso y ámbitos transitorios).

Desde el Ninject Documentation Wiki:

También puede definir fácilmente es el propietario alcances utilizando el .InScope (objeto o) método.

Encontrará algunos detalles reales sobre cómo funciona el ámbito de objetos en this Ninject Google Groups question & answer.

+2

+1 y enlace relacionado http://kohari.org/2009/03/06/cache-and-collect-lifecycle-management-in-ninject-20/ es una lectura obligatoria para entender los alcances de Ninject 2.0 –

+0

Después de leer artículos vinculados, ahora entiendo mejor cómo puedo controlar la vida útil de los objetos dependientes inyectados. Esto es bueno, pero sin una gran arquitectura, puede ser difícil de mantener. Parece que muy poca gente en la web da trucos acerca de cómo diseñar una buena aplicación de Windows y cómo iniciar el alcance del objeto en winform siempre teniendo en cuenta que muchas otras formas pueden funcionar juntas. Utilizo LightSpeed ​​of Mindscape y la memoria caché de uso de UnitOfWork y cuando tiene muchas formas de inversión que funcionan juntas, los datos a menudo deben compartirse. Cualquier cuerpo tiene una muestra concreta del proyecto? – Samuel

+0

@Samuel, para ser sincero, no he visto mucho en el camino de las aplicaciones de muestras de concreto que muestran Windows Forms con ORM y UnitOfWork empleadas en una aplicación bien diseñada. Ciertamente me gustaría verlos yo mismo si pudiera encontrar alguno. –

2

This article by Ayende in MSDN Magazine es aparentemente sobre NHibernate, y menciona la palabra inyectar solo una vez (y eso solo wrt AOP), pero la redacción de su pregunta me sugiere que será una gran fuente de reflexión al considerar cómo diseñar su aplicación .

0

También puede hacer que sus marcos dependan de una instancia de fábrica y confiar en la fábrica para realizar la agrupación de conexiones.

Alternativamente, puede usar Ninject para usar siempre la misma instancia de objeto para ese tipo en particular.

3

Finalmente encontré lo que estaba buscando.

crear una clase que hereda de 'Ninject.Activation.Provider (de T)'

Overrrides la función 'CreateInstance'

vincular a su interfaz con la que 'Ata (Por [Su interfaz]). ToProvider ([Su clase de proveedor]) '

Y ahora, podrá controlar cada instancia creada que esté asociada con la interfaz especificada.

Tenga en cuenta que puede pasar un tipo o una instancia al parámetro proveedor del método Bind. Con una instancia puede crear un proveedor antes de vincular sus interfaces y utilizar este proveedor en su código cuando desee crear una nueva instancia.

El proveedor junto con InScope permite una gran flexibilidad para cada lugar donde desea tener y la instancia de un objeto que se puede inyectar automáticamente y tener un alcance determinado.

Aquí se muestra un ejemplo:

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

Es bueno escuchar que sientes que tienes una respuesta. Mientras tengas métodos lambda completos (incompleto en VB hasta ver X (2010?), Uno típicamente usa Bind.ToMethod() - si realmente tienes algo lo suficientemente complejo como para requerir una clase, normalmente deberías hacerlo como contenedor cosa de diagnóstico como parte de la lógica de tu dominio. Pero definitivamente tiene un lugar correcto, especialmente si no tienes lambdas adecuados. –

Cuestiones relacionadas