2011-05-18 18 views
9

Actualicé el paquete Ninject.MVC3 de 2.2.1.0 a 2.2.2.0. Antes tenía acceso al objeto Kernel a través de la propiedad BootStrapper.Kernel pero en la nueva versión la propiedad Kernel está marcada como obsoleta. Aparece una advertencia que diceNinject.MVC3 La propiedad Kernel de Bootstrapper está marcada como Obsoleta. ¿Cómo puedo acceder al kernel?

'Public ReadOnly Property Kernel As Ninject.IKernel' está obsoleto: 'No use Ninject como localizador de servicios'.

¿Hay alguna forma diferente de acceder al kernel en la nueva versión?

Respuesta

5

La razón por la que esto se ha marcado como Obsoleto y se cambiará a interno en el futuro es que las personas tienden a utilizar Ninject como un localizador de servicios si es posible hacerlo. Pero Service Locator is an antipattern que no debe ser utilizado. Y como no queremos proporcionar una funcionalidad que ayude a crear software mal diseñado, se eliminará en el futuro.

Si esto necesita muchos cambios en su código, esto es señal de que su código está sufriendo de este malestar Dependency Injection y realmente debería cambiarlo a un mejor diseño.

  1. Limite al mínimo el acceso al kernel. Casi no hay ninguna situación en MVC en la que necesite algo distinto a la simple inyección de constructor. Por lo tanto, mi primer consejo es refactorizar a la inyección del constructor siempre que sea posible.
  2. Para estos raros casos donde necesita acceder al núcleo para crear otros objetos, debe inyectar una fábrica a la clase que necesita la nueva instancia e inyectar el núcleo en esta fábrica (si el Constructor tiene un parámetro Kernel, ll recibir la instancia haciendo la inyección).

Si realmente desea permanecer con el localizador de servicios, incluso si casi todos le dicen que no lo haga, tendrá que mantener una referencia estática usted mismo.

+3

Todos mis códigos relacionados con MVC, por ejemplo, los controladores tienen inyección de constructor, así que no hay problema. Pero en una situación, tengo que implementar un proveedor de Membresía personalizado donde quiero pasar IRepository al ctor. La solución ony que puedo encontrar está aquí http://stackoverflow.com/questions/5596441/inject-repository-to-custom-membership-provider-with-ninject. Esa es la razón por la que necesito acceder al kernel. ¿Conoces un mejor enfoque? – mahichR

+0

Verificar mi respuesta;) – Guillaume86

6

Si tiene una clase que (por algún motivo) necesita recuperar objetos del kernel Ninject, puede incluir el kernel como uno de los parámetros de construcción/propiedades inyectados en la clase. Este patrón es mejor en el sentido de que está declarando explícitamente que una clase en particular está usando el kernel, en lugar de tenerlo siempre disponible como lo hace el patrón de localizador de servicios.

Esto supone que Ninject agrega automáticamente un enlace de instancia del núcleo a sí mismo. Sé que solía hacer esto, pero si no puede agregar el enlace manualmente.

+0

Inyectar kernel en mis clases requerirá mucho cambio de código y violará mi arquitectura de aplicación existente. Entonces esto no es una opción. Gracias por la sugerencia, sin embargo. – mahichR

+0

¿Puedes publicar un código de ejemplo que muestre cómo/por qué la inyección de IKernel violaría tu arquitectura? – FMM

+0

Soy de la opinión de que debe adjuntar su instancia de IKernel a solo las clases relacionadas con la gestión de objetos; Definitivamente no a los servicios o la lógica de negocios. – Dann

0

Puede usar el Common Service Locator como gancho de ubicación de servicio en Ninject. El Localizador de servicios comunes solo le permite recuperar objetos, no inyectar objetos que ya tiene. Por supuesto, podrías hackear esta restricción, pero podrías crear fácilmente una clase estática que exponga el kernel de Ninject y haga referencia a eso en lugar de a BootStrapper.

2

En ASP.NET MVC 3, creo que DepedencyResolver es una manera limpia de obtener un localizador de servicios.

+2

Obtener instancias de DependencyResolver es exactamente igual que el patrón ServiceLocator. Para lo único que debe usarse es para crear instancias de controlador y solo debe ser invocado por el marco MVC y no por ningún código propio. –

+0

Bien, he respondido a la pregunta y dije que era la ubicación del servicio (no la inyección de dependencia), no creo que merezco el voto a favor – Guillaume86

Cuestiones relacionadas