团结和ASP.NET的WebForms - 此对象定义无参数的构造函数 [英] Unity and ASP.NET WebForms - No parameterless constructor defined for this object
问题描述
有没有人对如何使统一1.2或2.0的工作与ASP.NET的WebForms任何好的例子吗?
我觉得我有这个想通了,但很显然,我失去了一些东西。现在我得到的错误; 无参数的构造函数中定义此对象。我记得几年前得到这个错误,我只是不记得我做过什么。
显然,团结就是不工作,因为它应该因为一路上地方我忘记了什么东西。任何帮助将是AP preciated。
下面是我的一些code的:
Global.asax中
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;
使用System.Web.Security;
使用System.Web.SessionState;使用Microsoft.Practices.Unity;使用PIA35.Unity;命名空间PIA35.Web
{
公共类全球:System.Web.HttpApplication
{ 保护无效的Application_Start(对象发件人,EventArgs的发送)
{
IUnityContainer容器= Application.GetContainer();
PIA35.Web.IoC.Bootstrapper.Configure(容器);
}
}
}
下面是我的HttpModules web.config文件的部分:
<&的HttpModules GT;
<添加名称=ScriptModuleTYPE =System.Web.Handlers.ScriptModule,System.Web.Extensions程序,版本= 3.5.0.0,文化=中性公钥= 31BF3856AD364E35/>
<添加名称=UnityHttpModuleTYPE =PIA35.Unity.UnityHttpModule,PIA35.Unity/>
< /&的HttpModules GT;
这里的code为我的IoC的引导程序类。
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;
使用Microsoft.Practices.Unity;使用PIA35.Services.Interfaces;
使用PIA35.Services;
使用PIA35.DataObjects.Interfaces;
使用PIA35.DataObjects.SqlServer;命名空间PIA35.Web.IoC
{
公共静态类引导程序
{
公共静态无效配置(IUnityContainer容器)
{
容器
.RegisterType< ICategoryService,CategoryService>()
.RegisterType< ICustomerService,为CustomerService>()
.RegisterType< IOrderService,OrderService>()
.RegisterType< IOrderDetailService,OrderDetailService>()
.RegisterType< IProductService,ProductService>()
.RegisterType< ICategoryDao,SqlServerCategoryDao>()
.RegisterType< ICustomerDao,SqlServerCustomerDao>()
.RegisterType< IOrderDao,SqlServerOrderDao>()
.RegisterType< IOrderDetailDao,SqlServerOrderDetailDao>()
.RegisterType< IProductDao,SqlServerProductDao>();
}
}
}
这里的HttpApplicationStateExtensions.cs文件。
使用的System.Web;使用Microsoft.Practices.Unity;命名空间PIA35.Unity
{
公共静态类HttpApplicationStateExtensions
{
私人常量字符串GlobalContainerKey =GlobalUnityContainerKey; 公共静态IUnityContainer GetContainer(此HttpApplicationState应用程序)
{
application.Lock();
尝试
{
IUnityContainer容器=中的应用[GlobalContainerKey]作为IUnityContainer;
如果(集装箱== NULL)
{
集装箱=新UnityContainer();
应用[GlobalContainerKey] =容器;
}
返回容器中;
}
最后
{
application.UnLock();
}
}
}
}
下面是我的UnityHttpModule.cs文件。
使用系统;
使用System.Collections.Generic;
使用的System.Web;
使用System.Web.UI程序;
使用Microsoft.Practices.Unity;命名空间PIA35.Unity
{
公共类UnityHttpModule:IHttpModule的
{
#区域IHttpModule的成员 ///
///初始化模块和prepares它来处理请求。
///
///
///一个
///提供访问的方法,属性,
///和ASP.NET应用程序中通用于所有应用程序对象的事件
公共无效初始化(HttpApplication的情况下)
{
背景preRequestHandlerExecute + =在preRequestHandlerExecute。
} ///
资源///处置(内存除外)
///用于实现该模块。
///
///
公共无效的Dispose()
{
} #endregion 私人无效在preRequestHandlerExecute(对象发件人,EventArgs的发送)
{
IHttpHandler的处理程序= HttpContext.Current.Handler;
HttpContext.Current.Application.GetContainer()建设(handler.GetType(),处理程序)。 //用户控件是准备建立的页面初始化完成之后,
一页一页= HttpContext.Current.Handler的页面;
如果(页面!= NULL)
{
page.InitComplete + = OnPageInitComplete;
}
} //获取页面的控件树控件不包括页面本身
私人的IEnumerable GetControlTree(控制根)
{
的foreach(在root.Controls控制子)
{
产生收益的孩子;
的foreach(在GetControlTree控制C(子))
{
产生回报℃;
}
}
} //树立在页面的控件树每个控制
私人无效OnPageInitComplete(对象发件人,EventArgs的发送)
{
一页一页=(页)发送者;
IUnityContainer容器= HttpContext.Current.Application.GetContainer();
的foreach(在GetControlTree控制C(页))
{
container.BuildUp(c.GetType(),C);
}
}
}
}
下面是我服务的一个类的实例。
命名空间PIA35.Services
{
公共类CategoryService:ICategoryService
{ #地区的依赖注入 私人ICategoryDao categoryDao; 公共CategoryService(ICategoryDao CategoryDao)
{
this.categoryDao = CategoryDao;
} #endregion
#区域ICategoryService成员 公开名单GETALL()
{
返回categoryDao.GetAll()了ToList()。
} 公共类别GetById(INT的CategoryId)
{
返回categoryDao.GetById(类别ID);
} 公共无效添加(分类模型)
{
categoryDao.Insert(模型);
} 公共无效更新(分类模型)
{
categoryDao.Update(模型);
} 公共无效删除(分类模型)
{
categoryDao.Delete(模型);
} #endregion
}
}
我看到它已经回答了,但只是想我要指出的是,您要同步所有GetContainer调用你的锁定模式。到Application.Lock()的调用实际取出的applicationState写锁,是一个单独的对象,在你的web应用,你将看到的问题,如果你想扩展这一点。
要收拾这件事你可以做一个双重检查锁。像这样的:
公共静态IUnityContainer GetContainer(此HttpApplicationState应用程序)
{
IUnityContainer容器=中的应用[GlobalContainerKey]作为IUnityContainer;
如果(集装箱== NULL)
{
application.Lock();
尝试
{
容器=中的应用[GlobalContainerKey]作为IUnityContainer;
如果(集装箱== NULL)
{
集装箱=新UnityContainer();
应用[GlobalContainerKey] =容器;
}
}
最后
{
application.UnLock();
}
}
返回容器中;
}
我也想指出,我们已经使用,以确保控制和网页有自己的依赖关系建立了一个整齐的格局。我们基本上有一个通用PageBase和一般ControlBase我们所有的页面和控件继承。我只是进入pagebase为例:
公共抽象类SitePageBase< T> :SitePageBase其中T:SitePageBase< T>
{
保护覆盖无效的OnInit(EventArgs的发送)
{
BuildUpDerived();
base.OnInit(E);
} 保护无效BuildUpDerived()
{
ContainerProvider.Container.BuildUp(这是T);
}
}
然后在我们的页面,我们可以简单地从通用基础派生它会看起来积聚后。
公共部分类默认:SitePageBase<默认>
{
[依赖]
公共IContentService {contentService的获取;组; } 保护覆盖无效在preRender(EventArgs的发送)
{
this.label.Text = ContentService.GetContent(LabelText的);
}
}
Does anyone have any good examples of how to make Unity 1.2 or 2.0 work with ASP.NET WebForms?
I thought I had this figured out, but evidently I'm missing something. Now I'm getting the error; "No parameterless constructor defined for this object". I remember getting this error a couple years ago, I and just don't remember what I did.
Obviously Unity isn't working as it should because somewhere along the way I've forgotten something. Any help would be appreciated.
Here's some of my code:
Global.asax
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; using System.Web.SessionState; using Microsoft.Practices.Unity; using PIA35.Unity; namespace PIA35.Web { public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { IUnityContainer container = Application.GetContainer(); PIA35.Web.IoC.Bootstrapper.Configure(container); } } }
Here's my httpModules section of the web.config file:
<httpModules> <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add name="UnityHttpModule" type="PIA35.Unity.UnityHttpModule, PIA35.Unity"/> </httpModules>
Here's the code for my IoC bootstrapper class.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.Practices.Unity; using PIA35.Services.Interfaces; using PIA35.Services; using PIA35.DataObjects.Interfaces; using PIA35.DataObjects.SqlServer; namespace PIA35.Web.IoC { public static class Bootstrapper { public static void Configure(IUnityContainer container) { container .RegisterType<ICategoryService, CategoryService>() .RegisterType<ICustomerService, CustomerService>() .RegisterType<IOrderService, OrderService>() .RegisterType<IOrderDetailService, OrderDetailService>() .RegisterType<IProductService, ProductService>() .RegisterType<ICategoryDao, SqlServerCategoryDao>() .RegisterType<ICustomerDao, SqlServerCustomerDao>() .RegisterType<IOrderDao, SqlServerOrderDao>() .RegisterType<IOrderDetailDao, SqlServerOrderDetailDao>() .RegisterType<IProductDao, SqlServerProductDao>(); } } }
Here's the HttpApplicationStateExtensions.cs file.
using System.Web; using Microsoft.Practices.Unity; namespace PIA35.Unity { public static class HttpApplicationStateExtensions { private const string GlobalContainerKey = "GlobalUnityContainerKey"; public static IUnityContainer GetContainer(this HttpApplicationState application) { application.Lock(); try { IUnityContainer container = application[GlobalContainerKey] as IUnityContainer; if (container == null) { container = new UnityContainer(); application[GlobalContainerKey] = container; } return container; } finally { application.UnLock(); } } } }
Here's my UnityHttpModule.cs file.
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using Microsoft.Practices.Unity; namespace PIA35.Unity { public class UnityHttpModule : IHttpModule { #region IHttpModule Members /// ///Initializes a module and prepares it to handle requests. /// /// ///An ///that provides access to the methods, properties, ///and events common to all application objects within an ASP.NET application public void Init(HttpApplication context) { context.PreRequestHandlerExecute += OnPreRequestHandlerExecute; } /// ///Disposes of the resources (other than memory) ///used by the module that implements . /// /// public void Dispose() { } #endregion private void OnPreRequestHandlerExecute(object sender, EventArgs e) { IHttpHandler handler = HttpContext.Current.Handler; HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler); // User Controls are ready to be built up after the page initialization is complete Page page = HttpContext.Current.Handler as Page; if (page != null) { page.InitComplete += OnPageInitComplete; } } // Get the controls in the page's control tree excluding the page itself private IEnumerable GetControlTree(Control root) { foreach (Control child in root.Controls) { yield return child; foreach (Control c in GetControlTree(child)) { yield return c; } } } // Build up each control in the page's control tree private void OnPageInitComplete(object sender, EventArgs e) { Page page = (Page)sender; IUnityContainer container = HttpContext.Current.Application.GetContainer(); foreach (Control c in GetControlTree(page)) { container.BuildUp(c.GetType(), c); } } } }
Here's an example of one of my service classes.
namespace PIA35.Services { public class CategoryService : ICategoryService { #region Dependency Injection private ICategoryDao categoryDao; public CategoryService(ICategoryDao CategoryDao) { this.categoryDao = CategoryDao; } #endregion #region ICategoryService Members public List GetAll() { return categoryDao.GetAll().ToList(); } public Category GetById(int CategoryId) { return categoryDao.GetById(CategoryId); } public void Add(Category model) { categoryDao.Insert(model); } public void Update(Category model) { categoryDao.Update(model); } public void Delete(Category model) { categoryDao.Delete(model); } #endregion } }
I see it has already been answered but just thought I would point out that you are synchronising all the calls to GetContainer with your locking pattern. A call to Application.Lock() actually takes out a write lock on the applicationState which is a singleton object in your web application and you will see issues if you want to scale this.
To tidy this up you could do a double checked lock. like this:
public static IUnityContainer GetContainer(this HttpApplicationState application)
{
IUnityContainer container = application[GlobalContainerKey] as IUnityContainer;
if (container == null)
{
application.Lock();
try
{
container = application[GlobalContainerKey] as IUnityContainer;
if (container == null)
{
container = new UnityContainer();
application[GlobalContainerKey] = container;
}
}
finally
{
application.UnLock();
}
}
return container;
}
I would also like to point out a neat pattern that we have used to ensure Controls and Pages have their Dependencies built up. We basically have a Generic PageBase and Generic ControlBase that all our pages and controls inherit from. I will just go into the pagebase as an example:
public abstract class SitePageBase<T> : SitePageBase where T : SitePageBase<T>
{
protected override void OnInit( EventArgs e )
{
BuildUpDerived();
base.OnInit( e );
}
protected void BuildUpDerived()
{
ContainerProvider.Container.BuildUp( this as T );
}
}
Then in our Pages we can simply derive from Generic base and it will look after the build up.
public partial class Default : SitePageBase<Default>
{
[Dependency]
public IContentService ContentService { get; set; }
protected override void OnPreRender( EventArgs e )
{
this.label.Text = ContentService.GetContent("labelText");
}
}
这篇关于团结和ASP.NET的WebForms - 此对象定义无参数的构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!