MVCアプリケーションで動作させる例はたくさんあります。Webフォームではどのように行われますか?
回答:
WebFormsでNinjectを使用する手順は次のとおりです。
ステップ1-ダウンロード
Ninject-2.0.0.0-release-net-3.5とWebForm拡張機能Ninject.Web_1.0.0.0_With.log4netの2つのダウンロードが必要です(NLogの代替手段があります)。
次のファイルをWebアプリケーションで参照する必要があります:Ninject.dll、Ninject.Web.dll、Ninject.Extensions.Logging.dll、およびNinject.Extensions.Logging.Log4net.dll。
ステップ2-Global.asax
Globalクラスは、コンテナを作成するから派生しNinject.Web.NinjectHttpApplication
て実装する必要がCreateKernel()
あります。
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
コンストラクタがかかりますModule
。
ステップ3-モジュール
この場合YourWebModule
、モジュールは、Webアプリケーションが必要とするすべてのバインディングを定義します。
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public class YourWebModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ICustomerRepository>().To<CustomerRepository>();
}
この例では、ICustomerRepository
インターフェースが参照CustomerRepository
される場合は常に、コンクリートが使用されます。
ステップ4-ページ
それが完了すると、各ページはから継承する必要があります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]
-注入するNinjectを伝えICustomerRepository
CustomerRepoプロパティに。
すでにベースページがある場合は、ベースページをNinject.Web.PageBaseから派生させる必要があります。
ステップ5-マスターページ
必然的に、マスターページがあり、MasterPageが挿入されたオブジェクトにアクセスできるようにするには、マスターページを次の場所から派生させる必要がありますNinject.Web.MasterPageBase
。
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public partial class Site : MasterPageBase
{
#region Properties
[Inject]
public IInventoryRepository InventoryRepo { get; set; }
ステップ6-静的Webサービスメソッド
次の問題は、静的メソッドに注入できないことでした。明らかに静的なAjaxPageMethodがいくつかあったので、メソッドを標準のWebサービスに移動する必要がありました。繰り返しますが、Webサービスは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);
JavaScriptCompany.Web.Services.YourWebService.GetProductivity(user, onSuccess)
では、ではなく標準サービスを参照する必要がありますPageMethods.GetProductivity(user, onSuccess)
。
私が見つけた他の唯一の問題は、ユーザーコントロールにオブジェクトを挿入することでした。Ninject機能を使用して独自のベースUserControlを作成することは可能ですが、必要なオブジェクトのユーザーコントロールにプロパティを追加し、コンテナページでプロパティを設定する方が簡単であることがわかりました。箱から出してUserControlsをサポートすることは、Ninjectの「やること」リストにあると思います。
Ninjectの追加は非常に簡単で、雄弁なIoCソリューションです。Xml構成がないため、多くの人が気に入っています。Ninject構文だけでオブジェクトをシングルトンに変換するなどの他の便利な「トリック」があります- Bind<ILogger>().To<WebLogger>().InSingletonScope()
。WebLoggerを実際のシングルトン実装に変更する必要はありません。私はこれが好きです。
Ninject v3.0のリリース(2012年4月12日現在)により、より簡単になりました。インジェクションはHttpModuleを介して実装されるため、ページをカスタムページ/マスターページから継承する必要はありません。クイックスパイクの手順(およびコード)は次のとおりです。
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>();
}
デフォルト
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());
}
}
モデル
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";
}
}
出力ウィンドウからの結果
I am a model 1
From master: I am a model 1
NinjectWeb.cs
でApp_Start
。Ninjectを初期化するためのコードは、このファイルに含める必要があります。別のファイルにある場合(たとえばNinjectWebCommon.cs
、機能しません)。これは、NuGetを使用して他のNinjectパッケージよりも後でNinject.Webをインストールした場合に発生する可能性があります。
未解決のバグのため、ここでの回答は現在機能しません。これは、顧客のhttpmoduleを使用して、ninjectクラスから継承せずにページとコントロールに挿入する、@ Jasonの手順の修正バージョンです。
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>();
}
デフォルト
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());
}
}
モデル
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";
}
}
出力ウィンドウからの結果
I am a model 1
From master: I am a model 1
if (currentPage.Master!=null) { this.lazyKernel().Inject(currentPage.Master); }
ASP.NETWebフォームにNinject.Webを実装する手順は次のとおりです。
より詳細な例については、以下に私が見つけたいくつかの便利なリンクがあります。
Ninject.Web拡張機能をご覧ください。基本インフラストラクチャを提供します https://github.com/ninject/ninject.web
Steve Sanderson(Apress)による本「ProASP.NET MVC 2 Framework、2ndEdition」を確認してください。著者はNinjectを使用してデータベースに接続します。例を使用して、ニーズに合わせて調整できると思います。
public IGoalsService_CRUD _context { get; set; }
_contextオブジェクトが何らかの理由でnullに設定されています。残りの設定は次のとおりです
public partial class CreateGoal : Page
{
[Inject]
public IGoalsService_CRUD _context { get; set; }
}
グローバルファイルの場合
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>();
}
}