Posted by: dotnetninja | May 21, 2008

Unity And Asp.Net WebForms

This article is extending the latest one (DI with Unity and Asp.Net) by injecting properties to an Asp.Net page so than we do not have to use Unity container and resolve type we are using.

First try:

I have started by adding an property to page (MenuBL).

namespace UnityTest.WebApp
{
    public partial class _Default : System.Web.UI.Page
    {
        public UnityTest.Interfaces.IMenuBL MenuBL { get; set; }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                var mnuItems = MenuBL.GetUserMenuBL(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
                lvMenu.DataSource = mnuItems;
                lvMenu.DataBind();
            }
        }
    }
}

And adding to configuration file.

 
<unity>
		<containers>
			<container>
				<types>
          <type type="System.Web.UI.Page" mapTo="UnityTest.WebApp._Default" name="FirstPage">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,Microsoft.Practices.Unity.Configuration">
              <property name="MenuBL" propertyType="UnityTest.BLayer.MenuBL,UnityTest.BLayer">
              </property> 
            </typeConfig>
          </type>
					<type type="UnityTest.Interfaces.IMenuBL,UnityTest.Interfaces" mapTo="UnityTest.BLayer.MenuBL,UnityTest.BLayer">
						<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,Microsoft.Practices.Unity.Configuration">
							<property name="DALayer" propertyType="UnityTest.DALayer.MenuDB,UnityTest.DALayer"/>
						</typeConfig>
					</type>
					<type type="UnityTest.Interfaces.IMenuDAL,UnityTest.Interfaces"
                mapTo="UnityTest.DALayer.MenuDB,UnityTest.DALayer">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
                                     Microsoft.Practices.Unity.Configuration">
              <constructor>
                <param name="connString" parameterType="System.String">
                  <value value="LFConnectionString"/>
                </param>
              </constructor>
            </typeConfig>
          </type>
				</types>
			</container>
		</containers>
	</unity>

After firing project I have received System.TypeLoadException for System.Web.UI.Page (unable to find type), hm ok…

What if I manually register type directly in the page (just for test).

 
Global.Container.RegisterType<System.Web.UI.Page, UnityTest.WebApp._Default>("FirstPage"); 
Page p= Global.Container.Resolve<System.Web.UI.Page>("FirstPage");

Setting breakpoint to the Page p… and it works… ok when configuring, type was not recognized and it can register an Page.

Second try:

Adding full assembly qualified name to the config. file

<type type="System.Web.UI.Page, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mapTo="UnityTest.WebApp._Default, UnityTest.WebApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="FirstPage">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,Microsoft.Practices.Unity.Configuration">
              <property name="MenuBL" propertyType="UnityTest.BLayer.MenuBL,UnityTest.BLayer">
              </property> 
            </typeConfig>
          </type>

Now run and configuring goes well but property is not injected. Ok that was expected, Asp.Net is building the aspx and code behind file and pushing to the browser. I need to tell the container to look at System.Web.UI.Page to figure out what to inject.

Unity supports to inject an already create object using BuildUp<T>.

This can be done somewhere in the PageInit or PageLoad….

Third try:

namespace UnityTest.WebApp
{
    public partial class _Default : System.Web.UI.Page
    {
        public UnityTest.Interfaces.IMenuBL MenuBL { get; set; }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                 if (MenuBL == null)
                    Global.Container.BuildUp(this, "FirstPage"); 
                 var mnuItems = MenuBL.GetUserMenuBL(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
                lvMenu.DataSource = mnuItems;
                lvMenu.DataBind();
            }
        }
    }
}

AND IT WORKS……………

Same approach can be applied registering Windows Forms and WPF(Windows, Pages, UC).

Updated source code is here


Responses

  1. […] Check updated article :V1.1 […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: