web-dev-qa-db-fra.com

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

Il existe de nombreux exemples pour que cela fonctionne sur une application MVC. Comment cela se fait-il sur les formulaires Web?

79
nellbryant

Voici les étapes à suivre pour utiliser Ninject avec WebForms.

Step1 - Téléchargements

Deux téléchargements sont nécessaires - Ninject-2.0.0.0-release-net-3.5 et les extensions WebForm Ninject.Web_1.0.0.0_With.log4net (il existe une alternative NLog).

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 Global doit dériver de Ninject.Web.NinjectHttpApplication et implémenter 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;
        }

Le constructeur StandardKernel prend une Module.

Étape 3 - Module 

Le module, dans ce cas, YourWebModule, définit toutes les liaisons dont l'application Web aura besoin:

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, partout où l'interface ICustomerRepository est référencée, le CustomerRepository concret sera utilisé.

Étape 4 - Pages

Une fois que cela est fait, chaque page doit hériter 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] - indique à Ninject d'injecter ICustomerRepository dans la propriété CustomerRepo.

Si vous avez déjà une page de base, il vous suffit d’obtenir votre page de base à partir de Ninject.Web.PageBase.

Étape 5 - Pages maîtresses

Inévitablement, vous aurez des pages maîtres et pour permettre à une page maître d’accéder aux objets injectés, vous devez dériver votre page maître 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 - Méthodes de service Web statiques

Le problème suivant était de ne pas pouvoir injecter dans des méthodes statiques. Nous avions quelques méthodes de page Ajax, qui sont évidemment statiques. J'ai donc dû transférer les méthodes dans un service Web standard. De nouveau, le service Web doit dériver d'une classe Ninject - 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 JavaScript, vous devrez référencer le service standard - Company.Web.Services.YourWebService.GetProductivity(user, onSuccess), plutôt que PageMethods.GetProductivity(user, onSuccess).

Le seul autre problème que j'ai trouvé concernait l'injection d'objets dans les contrôles utilisateur. Bien qu'il soit possible de créer votre propre base UserControl avec les fonctionnalités Ninject, j'ai constaté qu'il était plus rapide d'ajouter une propriété au contrôle utilisateur pour l'objet requis et de définir la propriété dans la page du conteneur. Je pense que la prise en charge immédiate de UserControls figure dans la liste des tâches à effectuer de Ninject.

L'ajout de Ninject est assez simple et c'est une solution éloquente d'IoC. Beaucoup de gens l'aiment parce qu'il n'y a pas de configuration XML. Il propose d'autres "astuces" utiles, telles que convertir des objets en singletons avec la syntaxe Ninject uniquement - Bind<ILogger>().To<WebLogger>().InSingletonScope(). Il n’est pas nécessaire de changer WebLogger en une implémentation Singleton, c’est ce que j’aime.

78
Joe Ratzer

C'est devenu plus facile avec la sortie de Ninject v3.0 (à partir du 12/12/2012). L'injection étant implémentée via HttpModule, il n'est pas nécessaire que vos pages héritent d'une page/page maître personnalisée. Voici les étapes (et le code) pour un pic rapide.

  1. Créer un nouveau projet ASP.NET WebForms
  2. Utilisez NuGet pour ajouter la bibliothèque Ninject.Web (qui supprimera également les bibliothèques Ninject.Web.Common et Ninject)
  3. Enregistrez vos liaisons personnalisées dans la méthode App_Start/NinjectWebCommon.cs/RegisterServices
  4. Utilisez l'injection d'attribut 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>();
    } 

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

Des 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 de la fenêtre de sortie

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

Je pense que voici les étapes pour implémenter Ninject.Web sur Web Forms ASP.NET.

  1. Implémentez NinjectHttpApplication sur Global.asax. Pour le noyau, transmettez-le en implémentant NinjectModule.
  2. Sur chaque événement de chargement de page de formulaires Web au niveau du code derrière, implémentez Ninject.Web.PageBase. Ajoutez une classe d'instance avec le filtre [Inject] par dessus.

Pour un exemple plus détaillé, voici quelques liens utiles que j'ai trouvés:

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

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

8
nellbryant

Jetez un coup d'œil à l'extension Ninject.Web. Il fournit l'infrastructure de base https://github.com/ninject/ninject.web

4
Remo Gloor
public IGoalsService_CRUD _context { get; set; }

L'objet _context est défini sur null d'une manière ou d'une autre. Voici le reste des paramètres

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

Pour fichier global

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

public class Bindings : NinjectModule
{
    public override void Load()
    {
        Bind<goalsetterEntities>().To<goalsetterEntities>();
        Bind<IGoalsService_CRUD>().To<GoalsService_CRUD>();
    }
}
0
bshah

Consultez le livre "Framework ASP.NET MVC 2, 2e édition" de Steve Sanderson (Apress). L'auteur utilise Ninject pour se connecter à une base de données. Je pense que vous pouvez utiliser les exemples et les adapter à vos besoins.

0
jmpcm