Come posso implementare Ninject o DI su asp.net Web Form?

Ci sono un sacco di esempi per avere lavorato su un’applicazione MVC. Come e ‘ fatto su Web Form?

InformationsquelleAutor nellbryant | 2011-02-08



7 Replies
  1. 78

    Qui sono i passi per utilizzare Ninject con WebForms.

    Step1 – Download

    Ci sono due download richiesto – Ninject-2.0.0.0-release-net-3.5 e WebForm estensioni Ninject.Web_1.0.0.0_With.log4net (c’è un NLog alternativa).

    I seguenti file devono essere riferimento nell’applicazione web: Ninject.dll, Ninject.Web.dll, Ninject.Extensions.Logging.dll e Ninject.Extensions.Logging.Log4net.dll.

    Passo 2 – Global.asax

    Globale della classe deve derivare da Ninject.Web.NinjectHttpApplication e implementare CreateKernel(), che crea il contenitore:

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

    Il StandardKernel costruttore prende un Module.

    Passo 3 – Modulo

    Il Modulo, in questo caso YourWebModule, definisce tutte le associazioni di applicazioni web bisogno di:

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

    In questo esempio, laddove il ICustomerRepository interfaccia è fatto riferimento concreto CustomerRepository verrà utilizzato.

    Passo 4 – Pagine

    Una volta fatto, ogni pagina deve ereditare da 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);
                }

    Il InjectAttribute -[Inject] – dice Ninject per iniettare ICustomerRepository in CustomerRepo Proprietà.

    Se si dispone già di una pagina di base è sufficiente per ottenere la vostra pagina di base derivare dal Ninject.Web.PageBase.

    Passo 5 – Pagine Master

    Inevitabilmente, dovrete pagine master, e per consentire una MasterPage per accedere iniettato oggetti devi derivare la pagina master dal Ninject.Web.MasterPageBase:

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

    Passo 6 – Statico Metodi Del Servizio Web

    Il problema di non essere in grado di iniettare in metodi statici. Abbiamo avuto un paio di Ajax PageMethods, che ovviamente sono statici, quindi ho dovuto spostare i metodi standard di servizio web. Di nuovo, il servizio web deve derivare da una 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);

    In JavaScript è necessario per il riferimento a standard di servizio – Company.Web.Services.YourWebService.GetProductivity(user, onSuccess), piuttosto che PageMethods.GetProductivity(user, onSuccess).

    L’unico altro problema che ho trovato è stata l’iniezione di oggetti in Controlli Utente. Mentre è possibile creare la vostra propria base di UserControl con Ninject capacità, l’ho trovato più veloce per aggiungere una Proprietà per il controllo utente per l’oggetto richiesto e l’impostazione della Proprietà nella pagina contenitore. Penso di supporto UserControls out of the box è il Ninject “to-do” list.

    Aggiunta di Ninject è abbastanza semplice e si è eloquente Cio soluzione. Molte persone piace perchè non c’è nessuna configurazione Xml. Ha altri utili “trucchi” come trasformare gli oggetti in gravidanze con feto singolo con solo il Ninject sintassi – Bind<ILogger>().To<WebLogger>().InSingletonScope(). Non c’è bisogno di cambiare WebLogger in un vero e proprio Singleton un’implementazione, questo mi piace.

    • Questo funziona a meraviglia, ma ho provato questo su una nuova applicazione web form (dai modelli) e ha trovato che quando il Globale.asax.cs file di sessione predefinita metodi (ad esempio Application_Start) l’app ha restituito un errore criptico. Può essere ovvio che è necessario eliminare questi (come sono implementati in NinjectHttpApplication), ma mi ha colto di sorpresa.
    • Contento che sia stato utile. L’errore sembra strano, che cosa è l’eccezione? Ho un codice in Application_Start e funziona benissimo.
    • Ho dimenticato di chiamare il supertipo metodo NinjectHttpApplication.Application_Start Globale.asax.cs file del metodo Application_Start. Funziona quando lo faccio, altrimenti si è rotto.
    • Questa è una fantastica risposta! Ho una domanda però … al momento ho bisogno di implementare questo in un’applicazione che ha già la sua, personalizzato PageBase, e io non sono sicuro di come ottenere e Ninject a giocare bene insieme. È possibile fare?
    • Assolutamente, l’applicazione su cui sto lavorando adesso è una pagina di base (sempre una buona idea), basta avere la pagina di base per implementare PageBase.
    • Questo sembra ormai obsoleti. Il pacchetto NuGet, ninject.web, contiene un po ‘ di codice per l’avvio dell’app, rendendo la necessità di ereditare direttamente da NinjectHttpApplication obsoleti?
    • NuGet è sicuramente la strada da percorrere.
    • Seguendo questa guida, ho più volte questo messaggio di errore statico contenitore ha già un kernel associato. Qualcuno sa cosa potrebbe causare questo errore?
    • Si può ottenere che, se hai usato il pacchetto NuGet che inserire il codice NinjectWebCommon in App_start e Globali.asax(.cs) eredita da NinjectHttpApplication. Rimuovere NinjectWebCommon.cs e provare di nuovo.

  2. 67

    È diventato più facile con il rilascio di Ninject v3.0 (come del 4/12/2012). Iniezione avviene tramite HttpModule quindi non c’è bisogno di avere le vostre pagine ereditare da una Pagina personalizzata /MasterPage. Qui sono i passi (e il codice) per una rapida spike.

    1. Creare un nuovo ASP.NET WebForms progetto
    2. Utilizzare NuGet per aggiungere il Ninject.Web lib (che sarà anche portare giù il Ninject.Web.Comune e Ninject libs)
    3. Registrare il tuo associazioni personalizzate in App_Start /NinjectWebCommon.cs /RegisterServices metodo
    4. Attributo di utilizzo di iniezione sulle tue pagine

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

    Default

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

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

    Modelli

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

    Risultati dalla finestra di output

    I am a model 1
    From master: I am a model 1
    • Ciao Jason… sto cercando di implementare che… Ha i Ninject.Web lib da NuGet bene… ha creato il programma di avvio Automatico su App_Start … ho provato ad aggiungere un punto di interruzione sulla RegisterServices per eseguire il debug, ma non è mai arrivarci… devo aggiungere qualcos’altro?
    • Ciao Paolo, a seconda di che cosa host che si sta utilizzando (cioè, IIS IIS Express, la sonda cassini), può essere che il codice sia già da tempo in visual studio è collegato al processo. Ci sono modi per fare quel lavoro (stavo usando in IIS e di connessione al processo), ma prima di passare attraverso lo sforzo, mi piacerebbe vedere se il picco sopra funziona (cioè, si vede l’uscita). Se lo fa, poi si sa che Ninject almeno installato correttamente e funzionante.
    • Si può mettere Debugger.Pausa() in RegisterServices metodo per avviare il debug.
    • Ciao Jason. Sto avendo problemi a trovare questo lavoro, quindi mi chiedevo se questo è il resoconto completo? Vedo che il NinjectHttpModule è caricato a runtime, ma non è l’iniezione accadendo. Si può pensare di qualsiasi ragione questo dovrebbe essere il caso?
    • Come posso fare questo in un vb.net progetto?
    • Sto assumendo la struttura è la stessa come è di base .NET. VB non è il mio forte; questo ti aiuta quanto riguarda la sintassi va? converter.telerik.com
    • Grande esempio Grazie funziona la pagina/pagina master, ma non Asmx. Come faccio a farlo funzionare su Asmx? Grazie.
    • Ho trovato questo che non funziona con ninject 3.2.0.0
    • Ho provato a seguire la procedura su un’applicazione che sto lavorando, ma io non vedo l’iniezione di proprietà in corso. Posso impostare un punto di interruzione nel mio NinjectWebCommon del RegisterServices metodo e il punto di interruzione è successo, ma non iniettare prende posto sulla pagina. Ho provato a fare questo su un nuovo webforms progetto e funziona come previsto. Per quanto riguarda il mio progetto esistente, potrebbe essere causa di iniezione di non lavorare?
    • Assicurarsi che si dispone di un NinjectWeb.cs in App_Start. Il codice per inizializzare Ninject deve andare in questo file. Se è in un file separato (ad esempio NinjectWebCommon.cs non funziona). Questo può accadere se si installa Ninject.Web dopo l’altro Ninject pacchetti tramite NuGet.
    • Sto vivendo lo stesso problema mreyeros. Ho sia NinjectWeb e NinjectWebCommon. Si può specificare che il codice deve essere in NinjectWeb quando si intende “il codice per inizializzare Ninject”?
    • Penso che avete bisogno di controllare che l’interfaccia è pubblico e non privato. Provare che.

  3. 11

    La risposta qui attualmente non funziona a causa di un bug. Qui è una versione modificata di @Jason passi utilizzando un cliente di httpmodule di iniettare in pagine e controlli senza dover ereditare da ninject classi.

    1. Creare un nuovo ASP.NET WebForms progetto
    2. Utilizzare NuGet per aggiungere il Ninject.Web lib
    3. Registrare il tuo associazioni personalizzate in App_Start /NinjectWebCommon.cs /RegisterServices metodo
    4. Aggiungere InjectPageModule e registrare in NinjectWebCommon
    5. Attributo di utilizzo di iniezione sulle tue pagine

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

    Default

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

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

    Modelli

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

    Risultati dalla finestra di output

    I am a model 1
    From master: I am a model 1
    • Si prega di notare che questo non funziona per le pagine che non hanno una pagina Master. Ho modificato NinjectWebCommon con questo: if (currentPage.Master!=null) { this.lazyKernel().Inject(currentPage.Master); }
    • Grazie per aver dedicato del tempo a questo documento. Ho avuto lo stesso problema a lavorare con un lascito webforms progetto. Grazie a lei ha questo ordinati aggiustato il mio lavoro prima di Page_Init come è stato sempre chiamato troppo tardi, ma per il resto perfetto. Grazie @Adam!
    • Questa soluzione ha causato alcuni davvero casuale problemi per me. Per esempio, OnCommand eventi arrestato in esecuzione sul LinkButtons all’interno di Ripetitori. Non rompere tutti i code-behind eventi però.
  4. 8

    Penso che qui sono i passi per implementare Ninject.Sul Web ASP.NET Web Form.

    1. Implementare NinjectHttpApplication a livello Globale.asax. Per il Kernel, passare da attuare NinjectModule.
    2. Su ogni pagina web form evento load al codice dietro, implementare Ninject.Web.PageBase. Aggiungi istanza di classe con [Iniettare] filtro su di esso.

    Per esempio più dettagliato, di seguito sono alcuni link utili che ho trovato:

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

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

    • questo presuppone che hanno aggiunto il Ninject.Estensione Web, che è esattamente ciò che devi fare.
    • sì l’ho fatto. grazie.
    • Joeoncode link è stato molto utile. Grazie!
    • Entrambi i link sono morti.
    • joeandcode.net link ora è morto. Versione archiviata è qui: web.archive.org/web/20160324142135/http://joeandcode.net/post/…
  5. 4

    Guardare il Ninject.Estensione Web. Esso fornisce l’infrastruttura di base
    https://github.com/ninject/ninject.web

    • Ciao Remo. Che non sembrano mostrare i Moduli di Web di esempio.
    • So che dovrebbero dare l’esempio, ma il README dovrebbe essere >0 byte!
    • Sono d’accordo aggiornare il docu uno dei prio attività sulla lista bancomat.
    • È stato più di un anno e ancora nessuna documentazione?
    • È tutta questione di priorità e di quanto aiuto che viene dalla comunità. Un sacco di documentazione è stato aggiunto nel corso dell’anno passato. Non per Ninject.Web in quanto la ritengo meno importanti di altre caratteristiche, perché: a) WebForms è obsoleto – MVC invece b) non ho scritto questa estensione. Come tutti gli altri che ho per ottenere il kn circa l’estensione dal codice. c) io non la uso me – ci sono altri che possono scrivere il docu molto meglio di me. Ma a quanto pare non è importante per nessuno di loro. Il mio tempo libero è limitato come il tuo, e di conseguenza non posso fare tutto.
    • Downvoting proprio a causa della mancanza di documentazione non aumentare la mia motivazione o aumentare la priorità di scrivere questo docu per voi!
    • Dove prendi le tue idee? Sto male per il mio commento snarky da un anno indietro, ma a) non è stato accompagnato da un upvote b) era sarcastico, ma non whiney. Si prega di confutare il tutto legittima punti Remo fa in preferenza al lancio di giocattoli. BTW io sono sicuro che l’Unità è impressionante documentazione e potrebbe essere più al caso vostro. E si guarda in nellbryant o Jor R la risposta di provare a trovare un difetto che o si usa per scrivere un file readme o un campione di te.
    • Il downvote vale per la risposta, non la mancanza di documentazione. La domanda era per esempi, non ha fornito un esempio, ma invece punta al codice sorgente, per cui non c’è alcun esempio. Così, alla fine, non c’era esempio per i quali la domanda per.
    • In ogni caso, grazie per il fantastico DI quadro!

  6. 0

    Il libro “Pro ASP.NET MVC 2 Quadro, 2nd Edition” da Steve Sanderson (Apress). L’autore utilizza Ninject per la connessione con un database. Penso che si può utilizzare esempi e adattarlo alle vostre esigenze.

    • Sì, io ho quella che ha innescato me per fare la domanda. Come è fatto se l’applicazione web è la web form?
    • Questo è anche quanto io di solito andare su di esso in WebForms. Il trucco è che è necessario utilizzare il metodo Get del Kernel.
  7. 0
    public IGoalsService_CRUD _context { get; set; }

    Il _context oggetto viene impostato a null in qualche modo. Di seguito sono il resto delle impostazioni

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

    Globale File

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

Lascia un commento