82 votes

Comment puis-je implémenter Ninject ou DI sur asp.net Web Forms ?

Il y a beaucoup d’exemples pour avoir travaillé sur une application MVC. Comment fait-on sur les Web Forms ?

78voto

Joe R Points 10549

Voici les étapes pour utiliser Ninject avec les Formulaires web.

Etape 1 - Téléchargements

Il y a deux téléchargements requis - Ninject-2.0.0.0-release-net 3.5 et le Formulaire extensions Ninject.Web_1.0.0.0_With.log4net (il y a un NLog alternative).

Les fichiers suivants doivent être référencés dans l'application web: Ninject.dll, Ninject.Web.dll, Ninject.Extensions.Logging.dll et Ninject.Extensions.Logging.Log4net.dll.

Étape 2 - Global.asax

La classe Globale des besoins de dériver de l' Ninject.Web.NinjectHttpApplication et de mettre en oeuvre CreateKernel(), ce qui crée le conteneur:

using Ninject; using Ninject.Web;

namespace Company.Web {
    public class Global : NinjectHttpApplication


        protected override IKernel CreateKernel()
        {
            IKernel kernel = new StandardKernel(new YourWebModule());
            return kernel;
        }

L' StandardKernel constructeur prend un Module.

Étape 3 - Module

Le Module, dans ce cas - YourWebModule, définit toutes les liaisons de l'application web aura besoin de:

using Ninject;
using Ninject.Web;

namespace Company.Web
{
    public class YourWebModule : Ninject.Modules.NinjectModule
    {

        public override void Load()
        {
            Bind<ICustomerRepository>().To<CustomerRepository>();
        }   

Dans cet exemple, où l' ICustomerRepository interface est référencé à la de béton CustomerRepository sera utilisé.

Étape 4 - Pages

Une fois cela fait, chaque page doit hériter de la 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);
            }

L' InjectAttribute -[Inject] - dit Ninject à injecter ICustomerRepository dans le CustomerRepo de la Propriété.

Si vous avez déjà une page de base, vous avez juste besoin d'obtenir votre page de base pour dériver à partir de la Ninject.Web.PageBase.

Étape 5 - Pages Maîtres

Inévitablement, vous aurez des pages maîtres, et afin de permettre une MasterPage pour accéder injecté des objets dont vous aurez besoin pour tirer la page principale 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; }     

Étape 6 - Statique Des Méthodes De Service Web

Le problème suivant a été de ne pas pouvoir l'injecter dans des méthodes statiques. Nous avions un peu d'Ajax PageMethods, qui ne sont évidemment statique, donc j'ai dû déplacer les méthodes dans un service web standard. Encore une fois, le service web doit découler d'une Ninject classe - 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);

Dans votre code JavaScript que vous aurez besoin de faire référence à la norme de service - Company.Web.Services.YourWebService.GetProductivity(user, onSuccess), plutôt que d' PageMethods.GetProductivity(user, onSuccess).

Le seul autre problème que j'ai trouvé a été l'injection d'objets dans les Commandes de l'Utilisateur. Alors qu'il est possible de créer votre propre base de UserControl avec Ninject capacités, je l'ai trouvé plus rapide pour ajouter une Propriété à l'utilisateur le contrôle de l'objet et définition de la Propriété dans le conteneur de la page. Je pense que l'appui UserControls de la boîte est sur le Ninject "to-do" liste.

L'ajout de Ninject est assez simple et c'est un éloquent Cio solution. Beaucoup de gens l'aiment parce qu'il n'y a pas de configuration Xml. Il a d'autres "trucs", par exemple en transformant des objets dans les Singletons avec juste la Ninject syntaxe - Bind<ILogger>().To<WebLogger>().InSingletonScope(). Il n'est pas nécessaire de changer WebLogger en Singleton de mise en oeuvre, j'aime ça.

69voto

Jason Points 1948

Il est devenu plus facile avec la sortie de Ninject v3.0 (du 4/12/2012). L'Injection est réalisée via Http, donc il n'est pas nécessaire d'avoir de vos pages héritent d'une Page personnalisée / MasterPage. Voici les étapes (et le code) pour un rapide spike.

  1. Créer un nouveau ASP.NET WebForms projet
  2. Utiliser NuGet pour ajouter le Ninject.Web lib (qui va aussi diminuer l'Ninject.Web.Commune et Ninject libs)
  3. Enregistrer votre propre liaisons en App_Start / NinjectWebCommon.cs / RegisterServices méthode
  4. L'utilisation de l'attribut d'injection sur vos pages

NinjectWebCommon / RegisterServices

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IAmAModel>().To<Model1>();
    } 

Par défaut

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.Maître

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());
    }
}

Modèles

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";
    }
}

Résultats à partir de la fenêtre de sortie

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

12voto

Adam Points 1694

Ici, la réponse ne fonctionne pas en raison d'un bug ouvert. Voici une version modifiée de @Jason étapes à l'aide d'un client http pour les injecter dans des pages et des contrôles sans avoir besoin d'hériter de ninject classes.

  1. Créer un nouveau ASP.NET WebForms projet
  2. Utiliser NuGet pour ajouter le Ninject.Web lib
  3. Enregistrer votre propre liaisons en App_Start / NinjectWebCommon.cs / RegisterServices méthode
  4. Ajouter InjectPageModule et s'inscrire dans NinjectWebCommon
  5. L'utilisation de l'attribut d'injection sur vos pages

InjectPageModule.cs

 public class InjectPageModule : DisposableObject, IHttpModule
{
    public InjectPageModule(Func<IKernel> 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<Control> GetControlTree(Control root)
    {
        foreach (Control child in root.Controls)
        {
            yield return child;
            foreach (Control c in GetControlTree(child))
            {
                yield return c;
            }
        }
    }

    private readonly Func<IKernel> lazyKernel;
}

NinjectWebCommon / RegisterServices

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IHttpModule>().To<InjectPageModule>();
        kernel.Bind<IAmAModel>().To<Model1>();

    } 

Par défaut

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.Maître

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());
    }
}

Modèles

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";
    }
}

Résultats à partir de la fenêtre de sortie

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

8voto

nellbryant Points 805

Je pense ici sont les étapes pour mettre en œuvre Ninject.Web sur ASP.NET les Formulaires Web.

  1. Mettre en œuvre NinjectHttpApplication au niveau Mondial.asax. Pour le Noyau, faire passer par la mise en œuvre de NinjectModule.
  2. Sur chaque page web forms événement load du code derrière, de mettre en œuvre Ninject.Web.PageBase. Ajouter une instance de la classe [Injecter] filtre sur le dessus de cela.

Pour de plus amples exemple, ci-dessous quelques liens utiles que j'ai trouvé:

1.http://joeoncode.com/post/Ninject-2-and-WebForms.aspx

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

3voto

Remo Gloor Points 26195

Jetez un oeil à l’extension Ninject.Web. Il fournit l' infrastructure de base https://github.com/ninject/ninject.web

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X