Unity和ASP.NET WebForms – 没有为此对象定义的无参数构造函数

有没有人有任何关于如何使Unity 1.2或2.0与ASP.NET WebForms一起工作的好例子?

我以为我弄明白了,但显然我错过了一些东西。 现在我收到了错误; “没有为此对象定义无参数构造函数”。 我记得几年前收到这个错误,我只是不记得我做了什么。

显然Unity并没有按照它应有的方式运作,因为我忘记了某些事情。 任何帮助,将不胜感激。

这是我的一些代码:

Global.asax中

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Web.Security;
使用System.Web.SessionState;

使用Microsoft.Practices.Unity;

使用PIA35.Unity;

命名空间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(容器);
         }
     }
 }

这是web.config文件的httpModules部分:

 
     
     
 

这是我的IoC bootstrapper类的代码。

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用Microsoft.Practices.Unity;

使用PIA35.Services.Interfaces;
使用PIA35.Services;
使用PIA35.DataObjects.Interfaces;
使用PIA35.DataObjects.SqlServer;

命名空间PIA35.Web.IoC
 {
     public static class Bootstrapper
     {
         public static void Configure(IUnityContainer容器)
         {
            容器
                 .RegisterType ()
                 .RegisterType ()
                 .RegisterType ()
                 .RegisterType ()
                 .RegisterType ()
                 .RegisterType ()
                 .RegisterType ()
                 .RegisterType ()
                 .RegisterType ()
                 .RegisterType ();
         }
     }
 }

这是HttpApplicationStateExtensions.cs文件。

使用System.Web;

使用Microsoft.Practices.Unity;

名称空间PIA35.Unity
 {
     public static class HttpApplicationStateExtensions
     {
         private const string GlobalContainerKey =“GlobalUnityContainerKey”;

         public static IUnityContainer GetContainer(这个HttpApplicationState应用程序)
         {
             application.Lock();
            尝试
             {
                 IUnityContainer container = application [GlobalContainerKey] as IUnityContainer;
                 if(container == null)
                 {
                     container = new UnityContainer();
                     application [GlobalContainerKey] = container;
                 }
                回收容器;
             }
            最后
             {
                 application.UnLock();
             }
         }
     }
 }

这是我的UnityHttpModule.cs文件。

使用系统;
使用System.Collections.Generic;
使用System.Web;
使用System.Web.UI;
使用Microsoft.Practices.Unity;

名称空间PIA35.Unity
 {
    公共类UnityHttpModule:IHttpModule
     {
         #region IHttpModule成员

         ///
         ///初始化模块并准备处理请求。
         ///
         ///
         ///一个  
         ///提供对方法,属性的访问, 
         ///和ASP.NET应用程序中所有应用程序对象共有的事件 
         public void Init(HttpApplication context)
         {
             context.PreRequestHandlerExecute + = OnPreRequestHandlerExecute;
         }

         ///
         ///配置资源(内存除外) 
         ///由实现的模块使用。
         ///
         ///
         public void Dispose()
         {
         }

         #endregion

         private void OnPreRequestHandlerExecute(object sender,EventArgs e)
         {
             IHttpHandler handler = HttpContext.Current.Handler;
             HttpContext.Current.Application.GetContainer()。BuildUp(handler.GetType(),handler);

             //页面初始化完成后,就可以构建用户控件了
             Page page = HttpContext.Current.Handler as Page;
             if(page!= null)
             {
                 page.InitComplete + = OnPageInitComplete;
             }
         }

         //获取页面控制树中的控件,不包括页面本身
         private IEnumerable GetControlTree(Control root)
         {
             foreach(在root.Controls中控制孩子)
             {
                屈服回报孩子;
                 foreach(GetControlTree(child)中的控件c)
                 {
                    收益率c;
                 }
             }
         }

         //在页面的控制树中构建每个控件
         private void OnPageInitComplete(object sender,EventArgs e)
         {
            页面=(页面)发件人;
             IUnityContainer container = HttpContext.Current.Application.GetContainer();
             foreach(GetControlTree中的控件c(页面))
             {
                 container.BuildUp(c.GetType(),c);
             }
         }
     }
 }

这是我的一个服务类的示例。

命名空间PIA35.Services
 {
    公共类CategoryService:ICategoryService
     {

         #regiondependency injection

        私人ICategoryDao类别;

         public CategoryService(ICategoryDao CategoryDao)
         {
             this.categoryDao = CategoryDao;
         }

         #endregion


         #region ICategoryService成员

        公开列表GetAll()
         {
             return categoryDao.GetAll()。ToList();
         }

        公共类别GetById(int CategoryId)
         {
             return categoryDao.GetById(CategoryId);
         }

         public void Add(Category model)
         {
             categoryDao.Insert(模型);
         }

         public void Update(分类型号)
         {
             categoryDao.Update(模型);
         }

         public void删除(类别模型)
         {
             categoryDao.Delete(模型);
         }

         #endregion
     }
 }

我看到它已经得到了回答,但我想我会指出你正在使用锁定模式同步所有对GetContainer的调用。 对Application.Lock()的调用实际上会在applicationState上取出一个写锁定,它是Web应用程序中的单个对象,如果要扩展它,您将看到问题。

要整理一下,你可以做一个双重检查锁。 像这样:

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

我还想指出一个简洁的模式,我们已经用它来确保控件和页面的依赖关系建立起来。 我们基本上有一个Generic PageBase和Generic ControlBase,我们所有的页面和控件都inheritance自。 我将以页面库为例进行说明:

 public abstract class SitePageBase : SitePageBase where T : SitePageBase { protected override void OnInit( EventArgs e ) { BuildUpDerived(); base.OnInit( e ); } protected void BuildUpDerived() { ContainerProvider.Container.BuildUp( this as T ); } } 

然后在我们的页面中,我们可以简单地从Generic base派生,它将负责构建。

 public partial class Default : SitePageBase { [Dependency] public IContentService ContentService { get; set; } protected override void OnPreRender( EventArgs e ) { this.label.Text = ContentService.GetContent("labelText"); } } 

ObjectDataSource可以使用接口,但不能使用向导。 您可以使用该向导创建ObjectDataSource标记,然后对其进行编辑,并将TypeName属性值转换为您的接口名称。

然后,您需要指示ObjectDataSource如何创建对象。 我正在使用的方法是处理OnObjectCreating事件,所以在后面的代码我有:

 [Dependency] public IMyService Service { get; set; } protected void OnObjectCreating(...) { e.ObjectInstance = Service; } 

我有一段时间有一个工作项目,我开始了一个新项目并遇到了同样的问题。 做一些比较,并花了我一段时间。 但我记得你需要在global.asax中初始化它。

 Bootstrapper.Initialise(); // Missing in the global.asax