web-dev-qa-db-ja.com

NinjectまたはDIをasp.net Webフォームに実装するにはどうすればよいですか?

MVCアプリケーションで動作させるための例はたくさんあります。 Webフォームではどのように行われますか?

80
nellbryant

WebフォームでNinjectを使用する手順は次のとおりです。

ステップ1-ダウンロード

2つのダウンロードが必要です- Ninject-2.0.0.0-release-net-3.5 およびWebForm拡張 Ninject.Web_1.0.0.0_With.log4net (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]_-ICustomerRepositoryをCustomerRepoプロパティに挿入するようにNinjectに指示します。

既にベースページがある場合は、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サービスメソッド

次の問題は、静的メソッドに注入できなかったことです。明らかに静的なAjax PageMethodがいくつかあったので、メソッドを標準の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);
_

JavaScriptでは、Company.Web.Services.YourWebService.GetProductivity(user, onSuccess)ではなく、標準サービス-PageMethods.GetProductivity(user, onSuccess)を参照する必要があります。

私が見つけた他の唯一の問題は、ユーザーコントロールにオブジェクトを挿入することでした。 Ninject機能を使用して独自のベースUserControlを作成することは可能ですが、必要なオブジェクトのユーザーコントロールにプロパティを追加し、コンテナページでプロパティを設定する方が簡単です。すぐにUserControlsをサポートすることは、Ninjectの「やること」リストに載っていると思います。

Ninjectの追加は非常に簡単で、雄弁なIoCソリューションです。 Xml構成がないため、多くの人が気に入っています。 Ninject構文-Bind<ILogger>().To<WebLogger>().InSingletonScope()だけでオブジェクトをシングルトンに変えるなど、他の便利な「トリック」があります。 WebLoggerを実際のシングルトン実装に変更する必要はありません、私はこれが好きです。

79
Joe Ratzer

Ninject v3.0のリリース(2012年4月12日現在)で簡単になりました。インジェクションはHttpModuleを介して実装されるため、ページをカスタムPage/MasterPageから継承する必要はありません。クイックスパイクの手順(およびコード)は次のとおりです。

  1. 新しいASP.NET WebFormsプロジェクトを作成する
  2. NuGetを使用してNinject.Web libを追加します(Ninject.Web.CommonおよびNinjectライブラリもダウンします)
  3. App_Start/NinjectWebCommon.cs/RegisterServicesメソッドでカスタムバインディングを登録します
  4. ページで属性インジェクションを使用する

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

サイトマスター

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
68
Jason

ここの答え 現在、 未解決のバグ が原因で機能しません。顧客のhttpmoduleを使用して、ninjectクラスから継承することなくページとコントロールに挿入する@Jasonの手順の修正版を次に示します。

  1. 新しいASP.NET WebFormsプロジェクトを作成する
  2. NuGetを使用してNinject.Web libを追加します
  3. App_Start/NinjectWebCommon.cs/RegisterServicesメソッドでカスタムバインディングを登録します
  4. InjectPageModuleを追加し、NinjectWebCommonに登録します
  5. ページで属性インジェクションを使用する

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
12
Adam Bell

ASP.NET WebフォームにNinject.Webを実装する手順は次のとおりだと思います。

  1. Global.asaxでNinjectHttpApplicationを実装します。カーネルの場合、NinjectModuleを実装して渡します。
  2. コードビハインドの各Webフォームページ読み込みイベントで、Ninject.Web.PageBaseを実装します。その上に[Inject]フィルターを使用してインスタンスクラスを追加します。

より詳細な例については、私が見つけたいくつかの便利なリンクを以下に示します。

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

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

8
nellbryant

Ninject.Web拡張機能をご覧ください。基本インフラストラクチャを提供します https://github.com/ninject/ninject.web

4
Remo Gloor
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>();
    }
}
0
bshah

Steve Sanderson(Apress)の本「Pro ASP.NET MVC 2 Framework、2nd Edition」を確認してください。著者はNinjectを使用してデータベースに接続します。例を使用して、ニーズに合わせて調整できると思います。

0
jmpcm