Es gibt viele Beispiele dafür, wie es in einer MVC-Anwendung funktioniert. Wie wird es in Web Forms gemacht?
Es gibt viele Beispiele dafür, wie es in einer MVC-Anwendung funktioniert. Wie wird es in Web Forms gemacht?
Antworten:
Hier sind die Schritte zur Verwendung von Ninject mit WebForms.
Schritt 1 - Downloads
Es sind zwei Downloads erforderlich - Ninject-2.0.0.0-release-net-3.5 und die WebForm-Erweiterungen Ninject.Web_1.0.0.0_With.log4net (es gibt eine NLog-Alternative).
Die folgenden Dateien müssen in der Webanwendung referenziert werden: Ninject.dll, Ninject.Web.dll, Ninject.Extensions.Logging.dll und Ninject.Extensions.Logging.Log4net.dll.
Schritt 2 - Global.asax
Die Global-Klasse muss von ableiten Ninject.Web.NinjectHttpApplication
und implementieren CreateKernel()
, wodurch der Container erstellt wird:
using Ninject; using Ninject.Web;
namespace Company.Web {
public class Global : NinjectHttpApplication
protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel(new YourWebModule());
return kernel;
}
Der StandardKernel
Konstruktor nimmt a Module
.
Schritt 3 - Modul
In diesem Fall YourWebModule
definiert das Modul alle Bindungen, die die Webanwendung benötigt:
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public class YourWebModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ICustomerRepository>().To<CustomerRepository>();
}
In diesem Beispiel wird überall dort, wo auf die ICustomerRepository
Schnittstelle verwiesen wird, der Beton CustomerRepository
verwendet.
Schritt 4 - Seiten
Sobald dies erledigt ist, muss jede Seite erben von 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);
}
Das InjectAttribute -[Inject]
- weist Ninject an, ICustomerRepository
in die CustomerRepo-Eigenschaft zu injizieren .
Wenn Sie bereits eine Basisseite haben, müssen Sie nur Ihre Basisseite von der Ninject.Web.PageBase ableiten lassen.
Schritt 5 - Masterseiten
Zwangsläufig verfügen Sie über Masterseiten. Damit eine Masterseite auf injizierte Objekte zugreifen kann, müssen Sie Ihre Masterseite ableiten von Ninject.Web.MasterPageBase
:
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public partial class Site : MasterPageBase
{
#region Properties
[Inject]
public IInventoryRepository InventoryRepo { get; set; }
Schritt 6 - Statische Webdienstmethoden
Das nächste Problem bestand darin, nicht in statische Methoden injizieren zu können. Wir hatten einige Ajax PageMethods, die offensichtlich statisch sind, daher musste ich die Methoden in einen Standard-Webdienst verschieben. Auch hier muss der Webdienst von einer Ninject-Klasse abgeleitet sein - 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 Ihrem JavaScript müssen Sie auf den Standarddienst verweisen - Company.Web.Services.YourWebService.GetProductivity(user, onSuccess)
und nicht PageMethods.GetProductivity(user, onSuccess)
.
Das einzige andere Problem, das ich fand, war das Einfügen von Objekten in Benutzersteuerelemente. Es ist zwar möglich, ein eigenes Basis-UserControl mit Ninject-Funktionen zu erstellen, ich fand es jedoch schneller, dem Benutzersteuerelement eine Eigenschaft für das erforderliche Objekt hinzuzufügen und die Eigenschaft auf der Containerseite festzulegen. Ich denke, die sofortige Unterstützung von UserControls steht auf der "To-Do" -Liste von Ninject.
Das Hinzufügen von Ninject ist recht einfach und eine beredte IoC-Lösung. Viele Leute mögen es, weil es keine XML-Konfiguration gibt. Es hat andere nützliche "Tricks" wie das Verwandeln von Objekten in Singletons mit nur der Ninject-Syntax - Bind<ILogger>().To<WebLogger>().InSingletonScope()
. Es ist nicht erforderlich, WebLogger in eine tatsächliche Singleton-Implementierung zu ändern. Das gefällt mir.
Mit der Veröffentlichung von Ninject v3.0 (Stand: 12.04.2012) ist es einfacher geworden. Die Injektion wird über HttpModule implementiert, sodass Ihre Seiten nicht von einer benutzerdefinierten Seite / MasterPage geerbt werden müssen. Hier sind die Schritte (und der Code) für eine schnelle Spitze.
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>();
}
Standard
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());
}
}
Modelle
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";
}
}
Ergebnisse aus dem Ausgabefenster
I am a model 1
From master: I am a model 1
NinjectWeb.cs
in haben App_Start
. Ihr Code zum Initialisieren von Ninject muss in dieser Datei enthalten sein. Wenn es sich in einer separaten Datei befindet (z. B. NinjectWebCommon.cs
funktioniert es nicht). Dies kann passieren, wenn Sie Ninject.Web später als die anderen Ninject-Pakete mit NuGet installieren.
Die Antwort hier funktioniert derzeit aufgrund eines offenen Fehlers nicht . Hier ist eine modifizierte Version von @ Jasons Schritten, bei denen ein Kunden-http-Modul zum Einfügen in Seiten und Steuerelemente verwendet wird, ohne von ninject-Klassen erben zu müssen.
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>();
}
Standard
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());
}
}
Modelle
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";
}
}
Ergebnisse aus dem Ausgabefenster
I am a model 1
From master: I am a model 1
if (currentPage.Master!=null) { this.lazyKernel().Inject(currentPage.Master); }
Ich denke, hier sind die Schritte zum Implementieren von Ninject.Web auf ASP.NET Web Forms.
Im Folgenden finden Sie einige nützliche Links, die ich gefunden habe:
Schauen Sie sich die Ninject.Web-Erweiterung an. Es bietet die Basisinfrastruktur https://github.com/ninject/ninject.web
Lesen Sie das Buch "Pro ASP.NET MVC 2 Framework, 2. Ausgabe" von Steve Sanderson (Apress). Der Autor verwendet Ninject, um eine Verbindung mit einer Datenbank herzustellen. Ich denke, Sie können die Beispiele verwenden und sie an Ihre Bedürfnisse anpassen.
public IGoalsService_CRUD _context { get; set; }
Das _context-Objekt wird irgendwie auf null gesetzt. Im Folgenden sind die restlichen Einstellungen aufgeführt
public partial class CreateGoal : Page
{
[Inject]
public IGoalsService_CRUD _context { get; set; }
}
Für globale Datei
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>();
}
}