如何在asp.net Web窗体上实现Ninject或DI?

问题描述 投票:79回答:7

有很多例子可以让它在MVC应用程序上运行。它是如何在Web窗体上完成的?

asp.net webforms ninject
7个回答
78
投票

以下是将Ninject与WebForms一起使用的步骤。

第1步 - 下载

需要两次下载 - 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] - 告诉Ninject将ICustomerRepository注入CustomerRepo Property。

如果您已有基页,则只需要从Ninject.Web.PageBase派生基页。

第5步 - 母版页

不可避免地,您将拥有母版页,并允许母版页访问从qazxsw poi获取母版页所需的注入对象:

Ninject.Web.MasterPageBase

第6步 - 静态Web服务方法

下一个问题是无法注入静态方法。我们有一些Ajax PageMethods,它们显然是静态的,所以我不得不将这些方法转移到标准的Web服务中。同样,Web服务需要派生自Ninject类 - using Ninject; using Ninject.Web; namespace Company.Web { public partial class Site : MasterPageBase { #region Properties [Inject] public IInventoryRepository InventoryRepo { get; set; }

Ninject.Web.WebServiceBase

在您的JavaScript中,您需要引用标准服务 - 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); ,而不是Company.Web.Services.YourWebService.GetProductivity(user, onSuccess)

我发现的唯一其他问题是将对象注入用户控件。虽然可以使用Ninject功能创建自己的基本UserControl,但我发现在所需对象的用户控件中添加属性并在容器页面中设置属性会更快。我认为开箱即用的支持UserControls是在Ninject“待办事项”列表中。

添加Ninject非常简单,它是一个雄辩的IoC解决方案。很多人喜欢它,因为没有Xml配置。它还有其他有用的“技巧”,比如只用Ninject语法将对象转换为Singletons - PageMethods.GetProductivity(user, onSuccess)。没有必要将WebLogger更改为实际的Singleton implmentation,我喜欢这样。


67
投票

随着Ninject v3.0的发布(截至2012年4月12日),它变得更容易了。注入是通过HttpModule实现的,因此不需要让您的页面继承自定义的Page / MasterPage。以下是快速峰值的步骤(和代码)。

  1. 创建一个新的ASP.NET WebForms项目
  2. 使用NuGet添加Ninject.Web库(这也将删除Ninject.Web.Common和Ninject库)
  3. 在App_Start / NinjectWebCommon.cs / RegisterServices方法中注册自定义绑定
  4. 在页面上使用属性注入

NinjectWebCommon / RegisterServices

Bind<ILogger>().To<WebLogger>().InSingletonScope()

默认

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

的Site.Master

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";
    }
}

11
投票

由于I am a model 1 From master: I am a model 1 The answer here目前无效。以下是使用客户httpmodule注入页面和控件而不需要继承ninject类的@Jason步骤的修改版本。

  1. 创建一个新的ASP.NET WebForms项目
  2. 使用NuGet添加Ninject.Web库
  3. 在App_Start / NinjectWebCommon.cs / RegisterServices方法中注册自定义绑定
  4. 添加InjectPageModule并在NinjectWebCommon中注册
  5. 在页面上使用属性注入

InjectPageModule.cs

open bug

NinjectWebCommon / RegisterServices

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

默认

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IHttpModule>().To<InjectPageModule>();
        kernel.Bind<IAmAModel>().To<Model1>();

    } 

的Site.Master

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";
    }
}

8
投票

我认为这是在ASP.NET Web窗体上实现Ninject.Web的步骤。

  1. 在Global.asax上实现NinjectHttpApplication。对于内核,通过实现NinjectModule传递它。
  2. 在代码隐藏的每个Web表单页面加载事件上,实现Ninject.Web.PageBase。在其上添加[Inject]过滤器添加实例类。

有关更详细的示例,以下是我发现的一些有用链接:

1.I am a model 1 From master: I am a model 1

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



0
投票

查看Steve Sanderson(Apress)的“Pro ASP.NET MVC 2 Framework,第2版”一书。作者使用Ninject连接数据库。我认为您可以使用这些示例并根据您的需求进行调整。


0
投票
https://github.com/ninject/ninject.web

_context对象以某种方式设置为null。以下是其余设置

public IGoalsService_CRUD _context { get; set; }

对于全局文件

public partial class CreateGoal : Page
{
    [Inject]
    public IGoalsService_CRUD _context { get; set; }
}
© www.soinside.com 2019 - 2024. All rights reserved.