Want to follow this site? Here's the RSS feed.

Fundamentals of Themelia - Web Components

Monday, July 14, 2008

This documentation has been updated for Themelia Framework 2.0 Beta 5.

In a previous Themelia post, I discussed some of the advanced HTTP routing features in Themelia. In this post, I would like to introduce a Themelia concept that ties each of the advanced features together into a single unit: a Themelia Web Component

In essence, a Themelia web component is a package that automatically registers pre processors, processor factories, handler factories, mid processors, post processors, post state processors, error processors and a fall through processor. The idea is that by creating a web component, a developer may centralize all Themelia routing registration and configuration. Therefore, using a web component, you may now think of web development and HTTP routing in terms of componentization.

One major example of a web component is in Minima 3.1, which is completely packaged into a web component. As you can see from the below configuration snippet, installation of Minima is nothing more than the registration of a Themelia web component:

<themelia.web>
  <webDomains>
    <add>
      <components>
        <add key="Minima" type="Minima.Web.Routing.Component.MinimaComponent, Minima.Web">
          <parameters>
            <add name="page" value="/Page_/Information/Blog.aspx" />
            <add name="blogGuid" value="19277C41-7E4D-4AE0-A196-25F45AC48762" />
          </parameters>
        </add>
      </components>
    </add>
  </webDomains>
</themelia.web>

The registration of a Themelia web component should look fairly straight forward. In the components collection in web.config, just add in your component. Themelia will load the web component and automatically install any Themelia pipeline features that are in the web component.

A Themelia web component is made by creating a class that inherits from Themelia.Web.Routing.ComponentBase. This is an abstract class that requires you to implement the following signature:

public  void Register(FactoryDataList factoryDataList, ProcessorDataList processorDataList, HandlerDataList handlerDataList, AliasDataList aliasDataList, RedirectDataList redirectDataList);

Inside of the Register method, you then add the various Themelia parts to the appropriate list using a static method on the Data class for a particular entity.  Here's an example of how you add a factory to the factoryDataList:

factoryDataList.Add(FactoryData.Create("Sample.Web.Routing.ProcessorFactory, Sample.Web"));

If the factory, processor, handler, alias, or redirect accepts initialization parameters, you may also set them by just adding them as arguments:

processorDataList.Add(ProcessorData.Create<ProcessorData>("ForbiddenFallThroughProcessor", new Object[] { "This page is not publicly accessible" }));

Notice how the ProcessorData accepts a generic value.  For all processors other than and error processor, you may use the ProcessorData type.  However, for error processors you must use ErrorProcessorData.  Here's an example:

processorDataList.Add(ProcessorData.Create<ErrorProcessorData>("SavingError"));

Handlers, aliases, and redirects are created the same way as processors and factories.  Here's an example of a handler registration:

handlerDataList.Add(HandlerData.Create("Authentication", "webDomainPathStartsWith", "/authenticate/"));

At this point you should understand how to programmatically register your elements fairly well.  Here's a complete component example which ties together the past few examples:

public class SecurityComponent : Themelia.Web.Routing.ComponentBase
{
    //- @Register -//
    public override void Register(FactoryDataList factoryDataList, ProcessorDataList processorDataList, HandlerDataList handlerDataList, AliasDataList aliasDataList, RedirectDataList redirectDataList)
    {
        factoryDataList.Add(FactoryData.Create("Sample.Web.Routing.ProcessorFactory, Sample.Web"));
        factoryDataList.Add(FactoryData.Create("Sample.Web.Routing.HandlerFactory, Sample.Web"));
        processorDataList.Add(ProcessorData.Create<ProcessorData>("ForbiddenFallThroughProcessor", new Object[] { "This page is not publicly accessible" }));
        processorDataList.Add(ProcessorData.Create<ProcessorData>("HandlerRegistration"));
        processorDataList.Add(ProcessorData.Create<ErrorProcessorData>("SavingError"));
        handlerDataList.Add(HandlerData.Create("Authentication", "webDomainPathStartsWith", "/authenticate/"));
    }
}

That's all there is to it.  You can either register your elements in configuration or register them in a reusable or deployable component.  The option is yours.

Component in Web Domain Inheritance

When working with web domain inheritance, components are also copies along side processors, factories, and other elements.  Because of this, you do not need to declare the component type in more than one location.  This will be copies along with the component's contents.

Furthermore, the parameters of a component are also copied.  Because of this, you are also allowed to override individual parameters to change the value.  In the following example, there are two web domains.  The second copies all of the contents of the first, including parameters, but it changes the value of one of them.

<themelia.web>
  <webDomains>
    <add>
      <components>
        <add key="Minima" type="Minima.Web.Routing.Component.MinimaComponent, Minima.Web">
          <parameters>
            <add name="page" value="/Page_/Information/Blog.aspx" />
            <add name="blogGuid" value="19277C41-7E4D-4AE0-A196-25F45AC48762" />
          </parameters>
        </add>
      </components>
    </add>
    <add name="second" path="second" basedOn="root">
      <components>
        <add key="Minima">
          <parameters>
            <add name="blogGuid" value="A47C9A9F-5F5B-4b24-A032-992CEDE640C6" />
          </parameters>
        </add>
      </components>
    </add>
  </webDomains>
</themelia.web>

You also have the option to reset all parameters in a component when doing web domain inheritance.  Due to the completely different nature of component parameters from web domain elements, resetting them works differently.  While you use the resetSeries attribute on a web domain to erase entire handlers or processors, when working with component parameters, all you need to do is set the reset attribute on the parameters element to true.  Here's an example:

<themelia.web>
  <webDomains>
    <add>
      <components>
        <add key="Sample" type="Sample.Component, Minima.Web">
          <parameters>
            <add name="personId" value="2" />
          </parameters>
        </add>
      </components>
    </add>
    <add name="second" path="second" basedOn="root">
      <components>
        <add key="Sample">
          <parameters reset="true">
            <add name="firstName" value="john" />
            <add name="lastName" value="doe" />
          </parameters>
        </add>
      </components>
    </add>
  </webDomains>
</themelia.web>

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 License.

Powered by the Minima 3.1 and Squid Micro-Blogging Library.

Built on Themelia Framework 2.0

Developed using NetFXHarmonics DevServer 1.1.

(all of which are NetFXHarmonics products created by David Betz)

Mini-icons are part of the Silk Icons set of icons at famfamfam.com