QAT Insights

Highlighting recent QAT solution releases, insights, service and industry information, upcoming events, case studies, and press releases.

The Spring.NET Web Service Exporter Part 4 – Spring Configuration

July1

This is the last part of the Spring.NET Web Service Exporter example. I’ve shown the Web.config entries and the application details. Now we are only missing the Spring configuration file – named Spring.xml in my example. This is the whole configuration file (note that I have not set up transaction handling or other aspects in this example):

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">

Here the DAL is configured. Note that the dictionary is completely populated in the configuration. No coding necessary!

<!-- DAL-->
  <object id="LookUpDalRef" type="Qat.Demo.LookUpDal, QATDemo">
    <property name="Data">
      <dictionary key-type="string" value-type="Qat.Demo.LookUpDTO, QATDemo">
        <entry key="USA">
          <object type="Qat.Demo.LookUpDTO, QATDemo">
            <property name="Key" value="USA"/>
            <property name="Title" value="United States of America"/>
            <property name="Description"
              value="USA is the abbreviation for United States of America."/>
          </object>
        </entry>
        <entry key="UK">
          <object type="Qat.Demo.LookUpDTO, QATDemo">
            <property name="Key" value="UK"/>
            <property name="Title"
              value="United Kingdom of Great Britain and Northern Ireland"/>
            <property name="Description"
              value="UK is the abbreviation for United Kingdom of
              Great Britain and Northern Ireland."/>
          </object>
        </entry>
      </dictionary>
    </property>
  </object>

Configuring the service. Note the reference to the DAL object. You will not have to look up or instantiate anything in the code.

<!-- Services -->
<object id="LookUpService" type="Qat.Demo.LookUpService, QATDemo">
<property name="LookUpDal" ref="LookUpDalRef" />
</object>

And now the Web Service Exporter. You need to declare one exporter per web service. The name attribute sets the url:

  <!-- Web Service Exporters -->
  <object id="TestServiceExporter" name="/TestService.asmx"
      type="Spring.Web.Services.WebServiceExporter, Spring.Web">
    <property name="TargetName" value="LookUpService"/>
    <property name="Namespace" value="http://QAT/services"/>
    <property name="Description"
        value="Test Web Service.
          Demonstrates Spring.NET Web Service Exporter."/>

The typeAttributes allow using our custom DTO (in some
situations, you may also have to expose the [] Array type although in
this example it is able to construct the array type automatically).

      <property name="TypeAttributes">
        <list>
          <expression
            value="@[XmlInclude(T(Qat.Demo.LookUpDTO, QATDemo))]"/>
        </list>
      </property>

Exposing the web service methods. * can also be used as a wild card key. Note that only the most specific match will be applied to your method. If you enable session access in the * entry but have a separate entry for your method, the session access will not automatically be applied.

      <property name="MemberAttributes">
        <dictionary>
          <entry key="LookUp">
            <list>
              <object type="System.Web.Services.WebMethodAttribute,
                 System.Web.Services">
                <property name="Description" value="Looks up an
                  abbreviation."/>
              </object>
            </list>
          </entry>
          <entry key="LookUpAll">
            <list>
              <object type="System.Web.Services.WebMethodAttribute,
                   System.Web.Services">
                <property name="Description"
                    value="Returns array of all known abbreviations."/>
              </object>
            </list>
          </entry>

This method has session access enabled.

          <entry key="AccessSession">
            <list>
              <object type="System.Web.Services.WebMethodAttribute,
                  System.Web.Services">
                <property name="EnableSession" value="true"/>
              </object>
              <object type="System.Web.Services.WebMethodAttribute,
                  System.Web.Services">
                <property name="Description"
                  value="Accesses the User Session."/>
              </object>
            </list>
          </entry>
        </dictionary>
      </property>
    </object>
</objects>

Now our web service is ready. It will be exposed at <application context>/TestService.asmx. You also can use the LookUpService object directly either within the Spring configuration through

<property name="..." ref="LookUpService"/>

or programmatically:

Spring.Context.IApplicationContext ctx =
   Spring.Context.Support.ContextRegistry.GetContext();
ILookUpService lookupService = ctx["LookUpService"] as ILookUpService;

That wasn’t too hard, was it? Once you actually take a closer look at Spring configuration, it is actually quite intuitive. You still may say that it would have been quicker to code the traditional way. With the simple example I’ve shown, you would be correct. But consider a large, enterprise-level application: Need to expose the service as a COM+ component as well? It’s now a matter of configuration (for more details, see the Spring.NET documentation). In a large application, separating implementation from configuration and reducing the amount of hand-written code to the essential business logic will greatly enhance the maintainability and flexibility and make the initial overhead worthwhile.

Anke

The Spring.NET Web Service Exporter Part 3 – The Business Logic

June22

In my previous posts here and here, I explained the advantages of using Spring.NET’s Web Service Exporter and how to initialize Spring and Spring Web Service Exporting in the Web.config file. Now we need a service to export. Below I’ve listed the most important parts of the application – for brevity, I’ll omit imports and namespace declarations.

The service must implement an interface that represents the service contract:

public interface ILookUpService
{
    LookUpDTO LookUp(string key);
    LookUpDTO[] LookUpAll();
    string AccessSession();
}

The service implementation:

public class LookUpService : ILookUpService
{
    #region private fields
    private ILookUpDal _lookUpDal;
    #endregion

    #region Properties
    public ILookUpDal LookUpDal
    {
        get { return _lookUpDal; }
        set { _lookUpDal = value; }
    }
    #endregion

    #region ILookUpService Members

    public LookUpDTO LookUp(string key)
    {
        return LookUpDal.LookUp(key);
    }

    public LookUpDTO[] LookUpAll()
    {
        return LookUpDal.LookUpAll();
    }

    public string AccessSession()
    {
        if (HttpContext.Current.Session != null)
        {
            // This accesses the current user's session
            if (HttpContext.Current.Session["First Accessed"] == null) {
                HttpContext.Current.Session["First Accessed"] =
                     string.Format("First accessed on {0:s}", DateTime.Now);
            }
            return HttpContext.Current.Session["First Accessed"] as string;
        }
        return "Session Not Found";
    }
    #endregion
}

The DAL – I’m only showing the implementation (the interface defines both public methods):

public class LookUpDal : ILookUpDal
{
    #region private fields
    private IDictionary _data;
    #endregion

    #region Properties
    public IDictionary Data
    {
        get { return _data; }
        set { _data = value; }
    }
    #endregion

    #region ILookUpDal Members
    public LookUpDTO LookUp(string key)
    {
        return Data.ContainsKey(key) ? Data[key] : null;
    }

    public LookUpDTO[] LookUpAll()
    {
        LookUpDTO[] array = new LookUpDTO[Data.Count];
        Data.Values.CopyTo(array, 0);
        return array;
    }
    #endregion
}

And the DTO:

public class LookUpDTO
{
    #region Private Fields
    private string _key;
    private string _title;
    private string _description;
    #endregion

    #region Properties
    public string Key
    {
        get { return _key; }
        set { _key = value; }
    }
    public string Title
    {
        get { return _title; }
        set { _title = value; }
    }
    public string Description
    {
        get { return _description; }
        set { _description = value; }
    }
    #endregion
}

I could have added the DAL code directly into the service for simplicity’s sake and reduced the code to three classes (service interface, service implementation and custom DTO) but it’s good practice to keep actual data access out of the service layer (that’s typically the application layer that combines the fine-grained data access operations into coarse-grained business methods and applies the transactions).

All we’re missing now is the actual Spring configuration file. Stay tuned!

Anke

« Older Entries