有许多使它在MVC应用程序上运行的示例。如何在Web窗体上完成?
Answers:
以下是将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属性。
如果您已经有了基本页面,则只需获取基本页面即可从Ninject.Web.PageBase派生。
步骤5-母版页
不可避免地,您将拥有母版页,并且要允许母版页访问注入的对象,您需要从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 PageMethods,它们显然是静态的,因此我不得不将这些方法移到标准的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语法-将对象变成Singleton Bind<ILogger>().To<WebLogger>().InSingletonScope()
。我喜欢将WebLogger更改为实际的Singleton实现。
Ninject v3.0的发布(截至2012年4月12日)变得更加容易。注入是通过HttpModule实现的,因此无需从自定义Page / MasterPage继承您的页面。以下是快速执行操作的步骤(和代码)。
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
NinjectWeb.cs
in App_Start
。您初始化Ninject的代码必须放在此文件中。如果在单独的文件中(例如NinjectWebCommon.cs
,它将不起作用)。如果您晚于其他使用NuGet的Ninject软件包安装Ninject.Web,则会发生这种情况。
由于存在打开的bug,此处的答案当前不起作用。这是@Jason步骤的修改版本,该步骤使用客户的httpmodule注入到页面和控件中,而无需继承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>();
}
默认
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
if (currentPage.Master!=null) { this.lazyKernel().Inject(currentPage.Master); }
我认为这是在ASP.NET Web窗体上实现Ninject.Web的步骤。
对于更详细的示例,下面是我找到的一些有用的链接:
看看Ninject.Web扩展。它提供了基础架构 https://github.com/ninject/ninject.web
查看Steve Sanderson(Apress)的书“ Pro ASP.NET MVC 2 Framework,第二版”。作者使用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>();
}
}