¿Cómo puedo implementar Ninject o DI en asp.net Web Forms?

Hay muchos ejemplos para que funcione en una aplicación MVC. ¿Cómo se hace en los formularios web?

Estos son los pasos para usar Ninject con WebForms.

Paso 1 – Descargas

Se requieren dos descargas: Ninject-2.0.0.0-release-net-3.5 y las extensiones de WebForm Ninject.Web_1.0.0.0_With.log4net (hay una alternativa de NLog).

Los siguientes archivos deben ser referenciados en la aplicación web: Ninject.dll, Ninject.Web.dll, Ninject.Extensions.Logging.dll y Ninject.Extensions.Logging.Log4net.dll.

Paso 2 – Global.asax

La clase Global debe derivarse de Ninject.Web.NinjectHttpApplication e implementar CreateKernel() , que crea el contenedor:

 using Ninject; using Ninject.Web; namespace Company.Web { public class Global : NinjectHttpApplication protected override IKernel CreateKernel() { IKernel kernel = new StandardKernel(new YourWebModule()); return kernel; } 

El constructor StandardKernel toma un Module .

Paso 3 – Módulo

El Módulo, en este caso YourWebModule , define todos los enlaces que necesitará la aplicación web:

 using Ninject; using Ninject.Web; namespace Company.Web { public class YourWebModule : Ninject.Modules.NinjectModule { public override void Load() { Bind().To(); } 

En este ejemplo, siempre que se haga referencia a la interfaz ICustomerRepository , se usará el CustomerRepository concreto.

Paso 4 – Páginas

Una vez hecho esto, cada página debe heredar de Ninject.Web.PageBase :

  using Ninject; using Ninject.Web; namespace Company.Web { public partial class Default : PageBase { [Inject] public ICustomerRepository CustomerRepo { get; set; } protected void Page_Load(object sender, EventArgs e) { Customer customer = CustomerRepo.GetCustomerFor(int customerID); } 

InjectAttribute -[Inject] – le dice a Ninject que inyecte ICustomerRepository en la propiedad CustomerRepo.

Si ya tiene una página base, solo necesita obtener su página base para derivar de Ninject.Web.PageBase.

Paso 5 – Páginas maestras

Inevitablemente, tendrá páginas maestras, y para permitir que una página maestra acceda a los objetos inyectados necesitará derivar su página maestra de Ninject.Web.MasterPageBase :

 using Ninject; using Ninject.Web; namespace Company.Web { public partial class Site : MasterPageBase { #region Properties [Inject] public IInventoryRepository InventoryRepo { get; set; } 

Paso 6: métodos del servicio web estático

El siguiente problema no fue poder inyectar en métodos estáticos. Teníamos algunos métodos de página de Ajax, que obviamente son estáticos, así que tuve que mover los métodos a un servicio web estándar. Una vez más, el servicio web debe derivar de una clase Ninject.Web.WebServiceBase : Ninject.Web.WebServiceBase :

 using Ninject; using Ninject.Web; namespace Company.Web.Services { [WebService(Namespace = "//tempuri.org/">http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.Web.Script.Services.ScriptService] public class YourWebService : WebServiceBase { #region Properties [Inject] public ICountbackRepository CountbackRepo { get; set; } #endregion [WebMethod] public Productivity GetProductivity(int userID) { CountbackService _countbackService = new CountbackService(CountbackRepo, ListRepo, LoggerRepo); 

En su JavaScript necesitará hacer referencia al servicio estándar: Company.Web.Services.YourWebService.GetProductivity(user, onSuccess) , en lugar de PageMethods.GetProductivity(user, onSuccess) .

El único otro problema que encontré fue inyectar objetos en los controles de usuario. Si bien es posible crear su propio UserControl base con capacidades de Ninject, me pareció más rápido agregar una propiedad al control del usuario para el objeto requerido y establecer la propiedad en la página del contenedor. Creo que el soporte de UserControls fuera de la caja está en la lista de tareas de Ninject.

Agregar Ninject es bastante simple y es una solución IoC eloquent. A muchas personas les gusta porque no hay una configuración Xml. Tiene otros “trucos” útiles como convertir objetos en Singletons con solo la syntax de Ninject – Bind().To().InSingletonScope() . No hay necesidad de cambiar WebLogger en una implementación de Singleton real, me gusta esto.

Se ha vuelto más fácil con el lanzamiento de Ninject v3.0 (a partir del 12/04/2012). La inyección se implementa a través de HttpModule, por lo que no es necesario que sus páginas se hereden de una Página / Página maestra personalizada. Estos son los pasos (y el código) para un aumento rápido.

  1. Crear un nuevo proyecto ASP.NET WebForms
  2. Utilice NuGet para agregar Ninject.Web lib (que también reducirá las libs Ninject.Web.Common y Ninject)
  3. Registre sus enlaces personalizados en el método App_Start / NinjectWebCommon.cs / RegisterServices
  4. Use la inyección de atributos en sus páginas

NinjectWebCommon / RegisterServices

  ///  /// Load your modules or register your services here! ///  /// The kernel. private static void RegisterServices(IKernel kernel) { kernel.Bind().To(); } 

Defecto

 public partial class _Default : System.Web.UI.Page { [Inject] public IAmAModel Model { get; set; } protected void Page_Load(object sender, EventArgs e) { System.Diagnostics.Trace.WriteLine(Model.ExecuteOperation()); } } 

Site.Master

 public partial class SiteMaster : System.Web.UI.MasterPage { [Inject] public IAmAModel Model { get; set; } protected void Page_Load(object sender, EventArgs e) { System.Diagnostics.Trace.WriteLine("From master: " + Model.ExecuteOperation()); } } 

Modelos

 public interface IAmAModel { string ExecuteOperation(); } public class Model1 : IAmAModel { public string ExecuteOperation() { return "I am a model 1"; } } public class Model2 : IAmAModel { public string ExecuteOperation() { return "I am a model 2"; } } 

Resultados de la ventana de salida

 I am a model 1 From master: I am a model 1 

La respuesta aquí actualmente no funciona debido a un error abierto . Aquí hay una versión modificada de los pasos de @Jason utilizando un httpmodule de cliente para inyectar en páginas y controles sin necesidad de heredar de las clases de ninject.

  1. Crear un nuevo proyecto ASP.NET WebForms
  2. Use NuGet para agregar la lib Ninject.Web
  3. Registre sus enlaces personalizados en el método App_Start / NinjectWebCommon.cs / RegisterServices
  4. Agregue InjectPageModule y regístrese en NinjectWebCommon
  5. Use la inyección de atributos en sus páginas

InjectPageModule.cs

  public class InjectPageModule : DisposableObject, IHttpModule { public InjectPageModule(Func lazyKernel) { this.lazyKernel = lazyKernel; } public void Init(HttpApplication context) { this.lazyKernel().Inject(context); context.PreRequestHandlerExecute += OnPreRequestHandlerExecute; } private void OnPreRequestHandlerExecute(object sender, EventArgs e) { var currentPage = HttpContext.Current.Handler as Page; if (currentPage != null) { currentPage.InitComplete += OnPageInitComplete; } } private void OnPageInitComplete(object sender, EventArgs e) { var currentPage = (Page)sender; this.lazyKernel().Inject(currentPage); this.lazyKernel().Inject(currentPage.Master); foreach (Control c in GetControlTree(currentPage)) { this.lazyKernel().Inject(c); } } private IEnumerable GetControlTree(Control root) { foreach (Control child in root.Controls) { yield return child; foreach (Control c in GetControlTree(child)) { yield return c; } } } private readonly Func lazyKernel; } 

NinjectWebCommon / RegisterServices

  private static void RegisterServices(IKernel kernel) { kernel.Bind().To(); kernel.Bind().To(); } 

Defecto

 public partial class _Default : System.Web.UI.Page { [Inject] public IAmAModel Model { get; set; } protected void Page_Load(object sender, EventArgs e) { System.Diagnostics.Trace.WriteLine(Model.ExecuteOperation()); } } 

Site.Master

 public partial class SiteMaster : System.Web.UI.MasterPage { [Inject] public IAmAModel Model { get; set; } protected void Page_Load(object sender, EventArgs e) { System.Diagnostics.Trace.WriteLine("From master: " + Model.ExecuteOperation()); } } 

Modelos

 public interface IAmAModel { string ExecuteOperation(); } public class Model1 : IAmAModel { public string ExecuteOperation() { return "I am a model 1"; } } public class Model2 : IAmAModel { public string ExecuteOperation() { return "I am a model 2"; } } 

Resultados de la ventana de salida

 I am a model 1 From master: I am a model 1 

Creo que aquí están los pasos para implementar Ninject.Web en formularios web ASP.NET.

  1. Implementar NinjectHttpApplication en Global.asax. Para Kernel, pásalo implementando NinjectModule.
  2. En cada evento de carga de página de formularios web en el código subyacente, implemente Ninject.Web.PageBase. Agregue clase de instancia con el filtro [Inyectar] encima.

Para un ejemplo más detallado, a continuación hay algunos enlaces útiles que encontré:

1. http://joeandcode.net/post/Ninject-2-with-WebForms-35

2. http://davidhayden.com/blog/dave/archive/2008/06/20/NinjectDependencyInjectionASPNETWebPagesSample.aspx

Eche un vistazo a la extensión Ninject.Web. Proporciona la infraestructura base https://github.com/ninject/ninject.web

Consulte el libro “Pro ASP.NET MVC 2 Framework, 2nd Edition” de Steve Sanderson (Apress). El autor usa Ninject para conectarse con una base de datos. Creo que puedes usar los ejemplos y adaptarlos a tus necesidades.

 public IGoalsService_CRUD _context { get; set; } 

El objeto _context se establece en nulo de alguna manera. Los siguientes son el rest de la configuración

 public partial class CreateGoal : Page { [Inject] public IGoalsService_CRUD _context { get; set; } } 

Para archivo global

 protected override IKernel CreateKernel() { IKernel kernel = new StandardKernel(new Bindings()); return kernel; } public class Bindings : NinjectModule { public override void Load() { Bind().To(); Bind().To(); } }