Istnieje wiele przykładów na to, aby działał on w aplikacji MVC. Jak to się robi w formularzach sieci Web?
Istnieje wiele przykładów na to, aby działał on w aplikacji MVC. Jak to się robi w formularzach sieci Web?
Odpowiedzi:
Oto kroki, aby używać Ninject z WebForms.
Krok 1 - Pobieranie
Wymagane są dwa pliki do pobrania - Ninject-2.0.0.0-release-net-3.5 i rozszerzenia WebForm Ninject.Web_1.0.0.0_With.log4net (istnieje alternatywa NLog ).
W aplikacji sieciowej muszą znajdować się odniesienia do następujących plików: Ninject.dll, Ninject.Web.dll, Ninject.Extensions.Logging.dll i Ninject.Extensions.Logging.Log4net.dll.
Krok 2 - Global.asax
Klasa Global musi pochodzić z Ninject.Web.NinjectHttpApplication
i zaimplementować CreateKernel()
, co tworzy kontener:
using Ninject; using Ninject.Web;
namespace Company.Web {
public class Global : NinjectHttpApplication
protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel(new YourWebModule());
return kernel;
}
StandardKernel
Konstruktor trwa Module
.
Krok 3 - Moduł
Moduł w tym przypadku YourWebModule
definiuje wszystkie powiązania, których będzie potrzebować aplikacja internetowa:
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public class YourWebModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ICustomerRepository>().To<CustomerRepository>();
}
W tym przykładzie wszędzie tam, gdzie ICustomerRepository
jest odniesienie do interfejsu, CustomerRepository
zostanie użyty beton .
Krok 4 - Strony
Gdy to zrobisz, każda strona musi dziedziczyć z 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]
- mówi Ninject wstrzyknąć ICustomerRepository
do CustomerRepo Property.
Jeśli masz już stronę podstawową, wystarczy, aby Twoja strona podstawowa pochodziła z Ninject.Web.PageBase.
Krok 5 - Strony wzorcowe
Nieuchronnie będziesz mieć strony wzorcowe i aby umożliwić MasterPage dostęp do wstrzykniętych obiektów, z których będziesz musiał wyprowadzić swoją stronę wzorcową Ninject.Web.MasterPageBase
:
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public partial class Site : MasterPageBase
{
#region Properties
[Inject]
public IInventoryRepository InventoryRepo { get; set; }
Krok 6 - statyczne metody usług internetowych
Następnym problemem była niemożność wstrzyknięcia do metod statycznych. Mieliśmy kilka Ajax PageMethods, które są oczywiście statyczne, więc musiałem przenieść te metody do standardowej usługi internetowej. Ponownie, usługa internetowa musi pochodzić z klasy 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);
W swoim JavaScript musisz odwołać się do standardowej usługi - Company.Web.Services.YourWebService.GetProductivity(user, onSuccess)
zamiast PageMethods.GetProductivity(user, onSuccess)
.
Jedynym innym problemem, jaki znalazłem, było wstrzykiwanie obiektów do kontroli użytkownika. Chociaż możliwe jest utworzenie własnej podstawowej UserControl z funkcjami Ninject, szybciej okazało się, że dodawanie właściwości do kontrolki użytkownika dla wymaganego obiektu i ustawienie właściwości na stronie kontenera jest możliwe. Myślę, że obsługa UserControls po wyjęciu z pudełka znajduje się na liście „rzeczy do zrobienia” Ninject.
Dodanie Ninject jest dość proste i jest to wymowne rozwiązanie IoC. Wiele osób to lubi, ponieważ nie ma konfiguracji Xml. Ma inne przydatne „sztuczki”, takie jak przekształcanie obiektów w Singletony za pomocą tylko składni Ninject - Bind<ILogger>().To<WebLogger>().InSingletonScope()
. Nie ma potrzeby zmieniania WebLoggera na rzeczywistą implementację Singletona, podoba mi się to.
Stało się to łatwiejsze dzięki wydaniu Ninject v3.0 (stan na 12.04.2012). Wstrzykiwanie jest realizowane za pośrednictwem HttpModule, więc nie ma potrzeby dziedziczenia stron po niestandardowej stronie / MasterPage. Oto kroki (i kod) dla szybkiego wzrostu.
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>();
}
Domyślna
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());
}
}
Modele
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";
}
}
Wyniki z okna wyników
I am a model 1
From master: I am a model 1
NinjectWeb.cs
in App_Start
. Twój kod inicjujący Ninject musi znajdować się w tym pliku. Jeśli jest w osobnym pliku (np NinjectWebCommon.cs
. Nie zadziała). Może się tak zdarzyć, jeśli zainstalujesz Ninject.Web później niż inne pakiety Ninject przy użyciu NuGet.
Odpowiedź tutaj obecnie nie działa z powodu otwartego błędu . Oto zmodyfikowana wersja kroków @ Jasona wykorzystujących httpmodule klienta do wprowadzania do stron i kontrolek bez konieczności dziedziczenia z klas ninject.
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>();
}
Domyślna
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());
}
}
Modele
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";
}
}
Wyniki z okna wyników
I am a model 1
From master: I am a model 1
if (currentPage.Master!=null) { this.lazyKernel().Inject(currentPage.Master); }
Myślę, że oto kroki, aby zaimplementować Ninject.Web w ASP.NET Web Forms.
Aby uzyskać bardziej szczegółowy przykład, poniżej znajduje się kilka przydatnych linków, które znalazłem:
Spójrz na rozszerzenie Ninject.Web. Zapewnia podstawową infrastrukturę https://github.com/ninject/ninject.web
Zapoznaj się z książką „Pro ASP.NET MVC 2 Framework, 2nd Edition” autorstwa Steve Sanderson (Apress). Autor używa Ninject do łączenia się z bazą danych. Myślę, że możesz wykorzystać przykłady i dostosować je do swoich potrzeb.
public IGoalsService_CRUD _context { get; set; }
Obiekt _context jest w jakiś sposób ustawiany na null. Poniżej przedstawiono pozostałe ustawienia
public partial class CreateGoal : Page
{
[Inject]
public IGoalsService_CRUD _context { get; set; }
}
Dla pliku globalnego
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>();
}
}