Spring.NET and DI with WebForms

Typically with a tool like Castle Windsor you have to setup the container in the Global handlers. For instance:

public class GlobalApplication : HttpApplication, IContainerAccessor
    {
        private static IWindsorContainer container;

        /// <summary>
        /// Provides a globally available access to the <see cref="IWindsorContainer" /> instance.
        /// </summary>
        public static IWindsorContainer WindsorContainer
        {
            get { return container; }
        }

        #region IContainerAccessor

        public IWindsorContainer Container
        {
            get { return container; }
        }

        #endregion

        public void Application_OnStart()
        {
            container = new WindsorContainer(new XmlInterpreter());
        }


Then on any corresponding page, you can retrieve the container, for example, I tend to create a basepage and access the factory, something like this:

public abstract class BasePage : Page
    {
        /// <summary>
        /// Exposes accessor for the <see cref="IDaoFactory" /> used by all pages.
        /// </summary>
        public IDaoFactory DaoFactory
        {
            get { return GlobalApplication.WindsorContainer.Resolve<IDaoFactory>(); }
        }


This pulls from the config to get the IDaoFactory, ie.

<components>
    <component id="primaryDaoFactory"
               type="FSData.DaoFactory, FSData"
               service="FSData.IDaoFactory, FSData">
      <parameters>
        <connectionString>#{connString}</connectionString>
      </parameters>
    </component>
  </components>

Inside the page, I would then use that factory:

IMissionDao dao = DaoFactory.GetMissionDao();

With Spring.NET’s Spring.Web this is all diverted into the configuration with no code required:

First, you setup the correct context – notice I’ve commented out the default context to instead using the webcontext:

<sectionGroup name="spring">
            <!--<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>-->
      <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
            <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
        </sectionGroup>

A description of this can be found in the Spring.NET help:

"The instantiation and configuration of the Spring.NET IoC container by the Spring.Web infrastructure is wholly transparent to application developers, who will typically never have to explicitly instatiate and configure an IoC container manually (by for example using the new operator in C#). In order to effect the transparent bootstrapping of the IoC container, the Spring.Web infrastructure requires the insertion of the following configuration snippet into each and every Spring.Web-enabled web application’s root Web.config file"

Next, you add the HttpHandler:

<httpHandlers>
      <add verb="*" path="*.aspx" type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/>
        </httpHandlers>


and HttpModule:

<httpModules>
      <add name="SpringModule" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
    </httpModules>

(Both of these are in the web.config)

Once these are setup once, you don’t have to worry about it again.

Now we need to actually use our DaoFactory in our page:

<spring>
        <context>
            <resource uri="config://spring/objects"/>
        </context>
        <objects xmlns="http://www.springframework.net">
            <description>An  example that demonstrates simple IoC features.</description>

      <object type="Default.aspx">
        <property name="DaoFactory" ref="primaryDaoFactory"/>
      </object>

      <object  name="primaryDaoFactory"
               type="FSData.DaoFactory, FSData">
        <constructor-arg name="connectionString" value="server=.SQLEXPRESS;database=dbFW;Integrated Security=true"/>
      </object>

        </objects>
    </spring>


This shows that the Default.aspx page has a dependency on ‘DaoFactory’ that will be injected into the page. I setup a property on the page:

public partial class _Default : System.Web.UI.Page
    {
        private IDaoFactory daoFactory;

        public IDaoFactory DaoFactory
        {
            set { daoFactory = value; }
            get { return daoFactory; }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            IAircraftDao acDao = daoFactory.GetAircraftDao();
            List<Aircrafts> ac = acDao.SelectAllAircraft();
        }
    }

* Update:

If you notice, I did have to add the ‘object type=Default.aspx’ above.  Well, let’s say you had a ton of pages and didn’t want to add every page in order to inject this daoFactory.  An alternative is to use a basepage class that inherits from Spring.Web.UI.Page with the following:

        private IDaoFactory daoFactory;
        public IDaoFactory DaoFactory
        {
            get
            {
                //return this.ApplicationContext.ConfigureObject(this, typeof(IDaoFactory).FullName);
                return daoFactory;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            daoFactory = (IDaoFactory)this.ApplicationContext.GetObject("primaryDaoFactory");
            base.OnInit(e);
        }

Since i want the DaoFactory to be a singleton and it’s scope to be the application, I updated the config as well:

<object  name="primaryDaoFactory"
           type="FSData.DaoFactory, FSData" scope="application" singleton="true">
    <constructor-arg name="connectionString" value="server=.\SQLEXPRESS;database=dbFW;Integrated Security=true"/>

This allows me to inject the DaoFactory into every page that uses the base class (granted I’ve probably not want this code in my code behind but that is another topic…)

So there you have it – the daoFactory is injected into the page, and is accessible. I find this to be a better approach than Castle Windsor once you get through the configuration aspects. Both however, are very powerful, so if anything, this shows an alternative way of handling DI in webforms.

Side note: Curious about Spring.NET with MS MVC ? Here is an approach one programmer has used…

also http://fredrik.nsquared2.com/ViewPost.aspx?PostID=465

Advertisements

3 thoughts on “Spring.NET and DI with WebForms

    1. yeah, needs to be fixed – so basically my old host (webhost4life) changed ownership and became one of the worst hosting companies ever… but… lol.. I was able to get the mysql data out at the eleventh hour through a data dump and imported into new host wordpress setup, has to do with the encoding type – something I’ve been meaning to fix just not much time lately. I also lost all the images used in past posts, to the point I’ve considered just deleting the old posts since they aren’t readable any longer

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