tutorial pages net mvc entre ejemplos diferencias asp asp.net-mvc-2 ioc-container ninject ninject-2

asp.net-mvc-2 - pages - web forms c# ejemplos



Inyección de propiedad en el controlador base utilizando Ninject 2 (2)

Al ampliar las ideas de Ruben Bartelink, puede crear una implementación personalizada de IInjectionHeuristic .

public class ControllerInjectionHeuristic : NinjectComponent, IInjectionHeuristic { private readonly IKernel kernel; public BaseControllerInjectionHeuristic(IKernel kernel) { this.kernel = kernel; } public bool ShouldInject(MemberInfo member) { if (member.ReflectedType != typeof(BaseController)) { return false; } var propertyInfo = member.ReflectedType.GetProperty(member.Name); object service = kernel.TryGet(propertyInfo.PropertyType); return service != null; } }

ControllerInjectionHeuristic inyectará cualquier propiedad (servicio) en BaseController para que el kernel pueda resolver el servicio.

Registre la implementación personalizada con el kernel.

var kernel = new StandardKernel(); kernel.Components.Add<IInjectionHeuristic, ControllerInjectionHeuristic>();

Otra solución al problema es usar OnActivation . ( Esta solución no ha sido probada, pero debería darle una idea de cómo proceder ).

public class ControllerModule : NinjectModule { public override void Load() { // Get all controller types. You could use // Ninject.Extensions.Conventions. IEnumerable<Type> controllerTypes = null; foreach (var controllerType in controllerTypes) { Bind(controllerType).ToSelf().InRequestScope() .OnActivation(ControllerActivation); } } private static void ControllerActivation(IContext context, object obj) { var controller = obj as BaseController; if (controller == null) { return; } controller.ProductService = context.Kernel.Get<IProductService>(); } }

Tengo el siguiente código en mi Global.aspx

protected override void OnApplicationStarted() { AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); RegisterAllControllersIn(Assembly.GetExecutingAssembly()); } protected override IKernel CreateKernel() { return new StandardKernel(new ServiceModule()); }

También tengo el siguiente Módulo Ninject:

internal class ServiceModule : NinjectModule { public override void Load() { Bind<IProductService>().To<ProductService>().InRequestScope(); } }

También tengo un controlador base:

public class BaseController : Controller { [Inject] public IProductService ProductService { get; set; } }

Este código funciona El problema que tengo es que me gustaría eliminar el atributo de inyección del controlador base y especificarlo en el Ninject ServiceModule. En otras palabras, ¿cómo voy a escribir una regla vinculante en el ServiceModule que le dice a Ninject que inyecte ProductService en la propiedad en el controlador base?

Si elimino el atributo obtendré una NullReferenceException.


El enlace basado en convenciones vive en http://github.com/ninject/ninject.extensions.conventions - uno implementa IBindingGenerator . Sin embargo, esto está relacionado con el descubrimiento de interfaces y servicios.

En general, la inyección de constructor es un buen enfoque predeterminado. Sin embargo, la manera en que funciona ASP.NET MVC hace que sea más difícil hacerlo (por lo tanto, FubuMVC, etc.). Entonces, la inyección de propiedades es la siguiente mejor opción.

Puede encontrar que usar OnActivation en su Bind puede permitirle hacer lo suficiente, y si puede, este es de lejos el más simple.

Caracterizaría lo que estás tratando de hacer como activación basada en convenciones. El problema es:

  • decidir qué vas a autoinyectar. ¿Vas a inyectar todo lo público que no sea concreto? ¿Todo lo que sabe tu Kernel? A menos que pueda obtener una definición clara de lo que quiere hacer, el proceso de inyección puede volverse impredecible y difícil de entender. Terminas depurando y explicando mucho a tus colegas.

  • haciéndolo eficiente. Ninject genera código dinámicamente detrás de escena para hacer eficiente la activación de una instancia (es decir, en el momento de caminar la clase buscando marcadores [Inject] genera código una vez para hacer eso que luego se jima como si lo hubieras escrito a mano )

Mirando el código, no hay una manera fácil de OOTB. Parece que agregar una IInjectionHeuristic personalizada haría el truco.

Sin embargo, si está metiendo esto en contenedores, necesita

  1. pausa y ve si puedes mantenerlo simple al no ir por este camino
  2. ir a la lista de correo ninject y buscar cosas similares
  3. si aún quieres hacerlo, envía un correo allí.