developer tip

asp.net Web Forms에서 Ninject 또는 DI를 어떻게 구현할 수 있습니까?

copycodes 2020. 10. 7. 07:46
반응형

asp.net Web Forms에서 Ninject 또는 DI를 어떻게 구현할 수 있습니까?


MVC 응용 프로그램에서 작동하는 데 대한 많은 예제가 있습니다. Web Forms에서 어떻게 수행됩니까?


다음은 WebForms에서 Ninject를 사용하는 단계입니다.

Step1-다운로드

Ninject-2.0.0.0-release-net-3.5 및 WebForm 확장 Ninject.Web_1.0.0.0_With.log4net (NLog 대안이 있음)의 두 가지 다운로드가 필요합니다 .

웹 응용 프로그램에서 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은 웹 애플리케이션에 필요한 모든 바인딩을 정의합니다.

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를 알려줍니다 ICustomerRepositoryCustomerRepo 속성에.

이미 기본 페이지가있는 경우 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 단계-정적 웹 서비스 방법

다음 문제는 정적 메서드에 주입 할 수 없었습니다. 분명히 정적 인 Ajax PageMethod가 몇 개 있었기 때문에 메소드를 표준 웹 서비스로 옮겨야했습니다. 다시 말하지만 웹 서비스는 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 구문을 사용하여 객체를 Singleton으로 변환하는 것과 같은 다른 유용한 "트릭"이 Bind<ILogger>().To<WebLogger>().InSingletonScope()있습니다. WebLogger를 실제 Singleton 구현으로 변경할 필요가 없습니다.


Ninject v3.0 (2012 년 4 월 12 일 기준)의 출시로 더 쉬워졌습니다. 주입은 HttpModule을 통해 구현되므로 페이지가 사용자 정의 페이지 / 마스터 페이지에서 상속받을 필요가 없습니다. 빠른 스파이크를위한 단계 (및 코드)는 다음과 같습니다.

  1. 새 ASP.NET WebForms 프로젝트 만들기
  2. NuGet을 사용하여 Ninject.Web lib를 추가합니다 (Ninject.Web.Common 및 Ninject libs도 중단됨).
  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());
    }
}

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

여기에 대한 대답은 현재 열린 버그 로 인해 작동하지 않습니다 . 다음은 ninject 클래스에서 상속 할 필요없이 고객 httpmodule을 사용하여 페이지와 컨트롤에 삽입하는 @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

ASP.NET Web Forms에서 Ninject.Web을 구현하는 단계는 다음과 같습니다.

  1. Global.asax에서 NinjectHttpApplication을 구현합니다. 커널의 경우 NinjectModule을 구현하여 전달합니다.
  2. On each web forms page load event at code behind, implement Ninject.Web.PageBase. Add instance class with [Inject] filter on top of it.

For more detailed example, below are some useful links I found:

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

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


Have a look at the Ninject.Web extension. It provides the base infrastructure https://github.com/ninject/ninject.web


Check the book "Pro ASP.NET MVC 2 Framework, 2nd Edition" by Steve Sanderson (Apress). The author uses Ninject to connect with a database. I think you can use the examples and adapt them to your needs.


public IGoalsService_CRUD _context { get; set; }

The _context object is being set to null somehow. Following are the rest of the settings

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

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

참고URL : https://stackoverflow.com/questions/4933695/how-can-i-implement-ninject-or-di-on-asp-net-web-forms

반응형