Skip to content

OpenAccess – using a base class for identity and version


Hi all,

This blogpost will not be that long. It is just a note for my previous posts on building an WCF architecture using OpenAccess.

If you are lucky to start on a new system from scratch and you use Telerik OpenAccess as your ORM (if you don’t use it, give it a whirl, it’s amazing) you will probably use the forward mapping wizard. The wizard enables you to take plain C# classes (decorated with the Persistent attribute) and create or update a database schema according to your defined mapping (a default one is applied if you don’t define one).

Anyway, you might find it cumbersome to define the identity for each and every persistent class you have in your system. The latest project I worked on had 500+ of those. But since OpenAccess is a ORM it naturally supports inheritance and can map those accordingly. Ok, to set the scene I need a common base class for all my persistent class that will hold the id of the object and the version of the object (OpenAccess uses the latter for optismistic concurrency if you wish to use that feature – I did).

Ok, lets take a look at our base class:

    [Telerik.OpenAccess.Persistent()]
    public abstract class BaseEntity
    {
        protected int id;
        protected int version;

        public int Id
        {
            get { return id; }
        }

        public int Version
        {
            get { return version; }
            set { version = value; }
        }
    }

Note: You can get the full solution including the source code for the base class from Teleriks Code Library.

The class is really simple. It is decorated with the Persistent attribute, includes protected fields and public properties for those fields. Note though, that since OpenAccess handles generation of new object identifiers (the id field) I only delcared a readonly property for the Id. Note also that the class is declared as abstract. Doing so will make sure that the class can never be instantiated directly. Let’s take a look at the forward mapping dialog for this class og how we define the mapping:

As you can see the inheritance strategy is set to Horizontal. That’s all 🙂
So, what does this mean to OpenAccess?
It will make OpenAccess treat this class as one that should never be mapped directly to a database table AND all descendants of this class (for example Customer class) will include the fields from the BaseEntity class. Ofcause it will include the fields you say, it is normal OOP procedure. Yes, but OpenAccess will also include the fields in the resulting table for the “table generating class”.
So far so good, let’s take a look at a possible descendant. Simple class I know, but it illustrates what goes on perfectly.

    [Telerik.OpenAccess.Persistent(IdentityField = "id", VersionField = "version")]
    public class BusinessPartner : BaseEntity
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

Our BusinessPartner class inherits from the BaseEntity class. It is also decorated with the Persistent attribute, but as opposed to the BaseEntity, it also defines the IdentityField and VersionField parameters of the Persistent attribute. These parameters will instruct OpenAccess on how to find the identity field and the version field for the BusinessPartner class. This class is also the table generating class, so the class is mapped to table in the database. Let’s see how it is mapped in the forward mapping wizard:

As you can see the identity type is set to be Single field, the Id field is defined as BaseEntity.Id and the key generator is HIGHLOW. As this class descends from our BaseEntity it also knows the fields of the super class. I used the HIGHLOW generator in this example, but it could have been any that supports the int type (the type of my identity field).
As for the concurrency settings they are pretty straight forward. The mechanism used is By version and the field is the BaseEntity.version field.
Note that the readonly textbox called base class, shows that our base class is the BaseEntity one.

When you build the project (if you have UpdateDatabase=True in your project settings) or when you hit the Telerik menu: OpenAccess->Database operations->Create/Update database your database schema is etiher created or updated. Let’s look at the resulting schema for the BusinessPartner class:

As you can see, the fields from the BaseEntity class (id and version) is defined in the business_partner table along with the fields (only name here) from the BusinesPartner class itself. The BaseEntity class does not have a corresponding table since it is abstract.

Conclusion: Instead of defining the identity and version fields in each and every persistent class, you should really consider making a base class common to all persistent classes. This abstract base class then serves as a kind of “template” for the resulting tables for the subclasses.

Hope you found the post useful.

Next time, I will take you through the connection settings for this project…

Cheers

Advertisements

Building a WCF architecture using OpenAccess – handling the scope


Howdy,

In my last post I was setting the scene for the WCF architecture.. now it’s time to do some code that actually does what the many words in my previous post talked about. But before I do that…let’s take a look on how the final solution will look like in terms of layers:

WCF services

This layer is the top most and will contain the endpoints for my services. Each service method will invoke a method in the Business services layer just below.

Business services

This layer contains all (ok, there not much to it yet, but it will be there later…trust me) business logic. A method within this layer also serves as a transaction demarcation. What I called “business transaction” in my previous post. So this is where the transaction handled by ObjectScope will get started and commited or rolled back. A business service method might invoke several repository methods in the Data access layer just below.

Data access

This layer contains all access to persistent objects. This is where LINQ queries will be executed and other CRUD like methods. So this is methods that uses and manipulates the persistence model.

All of the above layers have access to infrastructure services.. Huh? What is that!!..  Right now think of it as an assembly where you can put cross-cutting concerns for your layers. The first one of those concerns is the ContextManager.

The ContextManager

Remember the previous post ended up by concluding we needed a mechanism to make sure that during a service request we had an object scope (the same no matter how and where we referenced it) and also a clear transaction demarcation?  Lets deal with the object scope first.

I decided to create the ContextManager which essentially implements the following interface:

    public interface IContextManager
    {
        /// <summary>
        /// Attach a context
        /// </summary>
        void Attach();

        /// <summary>
        /// Detach a previously attached context
        /// </summary>
        void Detach();

        /// <summary>
        /// Readonly property to return the current context
        /// </summary>
        IManagedContext Current
        {
            get;
        }
    }

A full working solution including source is available at Teleriks Code Library.

In short an implementation of this interface can manage objects that implements the IManagedContext interface. I did one implementation of this interface called the WcfContextManager. When Attach is called it creates a new ObjectScopeContext which implements the IManagedContext interface. During creation of the context the object scope is created. Thus the ObjectScopeContext wraps the object scope and exposes it using a public property. Like:

    public class ObjectScopeContext : IManagedContext
    {
        private IObjectScope scope;

        public IObjectScope ObjectScope
        {
            get { return scope; }
            set { scope = value; }
        }

        public ObjectScopeContext()
        {
            ObjectScopeProvider.AdjustForDynamicLoad();
            scope = ObjectScopeProvider.GetNewObjectScope();
        }
    }

The created ObjectScopeContext instance is when put into a dictionary managed by the WcfContextManager using a string key that is known to the currently executing WCF service request. I chose to use the message id like:

    public class WcfContextManager : BaseContextManager
    {
        #region BaseContextManager Members

        /// <summary>
        /// Retrieve the key for the
        /// </summary>
        /// <returns></returns>
        protected override string GetContextKey()
        {
            return System.ServiceModel.OperationContext.Current.
IncomingMessageHeaders.MessageId.ToString();
        }

        protected override IManagedContext CreateManagedContext()
        {
            return new ObjectScopeContext();
        }

        #endregion
    }

So, to summarize: The WcfContextManager can manage ObjectScopeContext instances…each of those is “bound” to the currently executing Wcf request using the MessageId

So where do I perform the Attach and Detach.. in an WCF Behavior Extension naturally..

Attaching and detaching contexts

To start attaching and detaching contexts I will need a place to so..preferably then the request has been received and just before the reply is sent back. Lucky me WCF is flexible. I wrote a WCF endpoint behavior extension, that applies a dispatch behavior to the endpoint, like:

        public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
        {
            if (Enabled)
            {
                ContextBehaviorMessageInspector inspector = new ContextBehaviorMessageInspector();
                endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
            }
        }

The ContextBehaviorMessageInspector is added to the WCF request pipeline, so I can inspect (among other things) the message received from the client.. Let’s dive into the inspector. It implements the IDispatchMessageInspector and I implemented this interface in my ContextBehaviorMessageInspector like:

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            // Attach context using the default context manager
            ContextManagerFactory.Default.Attach();

            return Guid.NewGuid();
        }

        /// <summary>
        /// Perform action before sending the reply to the client
        /// </summary>
        /// <param name="reply"></param>
        /// <param name="correlationState">
        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            ContextManagerFactory.Default.Detach();
        }

And now I reached my goal:
Whenever I WCF request comes in a ObjectScopeContext is attached to the message Id of the request using the WcfContextManager presented earlier in the post. Just before the reply is sent to the client, the context is detached again.. and during the detach the object scope is actually disposed, too.

Furthermore, I can reference my ObjectScope everywhere in my code (the business services and repository layers above) by doing a ContextManagerFactory.Default.Current and I am guaranteed that I will get the same object scope each time I asked for it during a service request. Like:

        public void CreateCustomer(string name)
        {
            // Start the transaction on the scope if not already done
            if (!Context.ObjectScope.Transaction.IsActive)
                Context.ObjectScope.Transaction.Begin();

            try
            {
                // Perform the business work flow using the repositories
                customerRepository.CreateCustomer(name);

                // Commit the transaction if it is still active
                if (Context.ObjectScope.Transaction.IsActive)
                    Context.ObjectScope.Transaction.Commit();
            }
            catch (Exception e)
            {
                // Rollback the transaction if it is still active
                if (Context.ObjectScope.Transaction.IsActive)
                    Context.ObjectScope.Transaction.Rollback();
                throw e;
            }

        }

Note: In the above code I implemented a read only property on the BaseBusinessService class called Context that actually performs the type casting from IManagedContext to ObjectScopeContext

And even better: It has no dependencies whatsoever on how you host your WCF service. It can be self hosting (like in my example), hosted by WAS, hosted by IIS… whatever.. it will still work since I used no host-dependent mechanism (like HttpContext) to “bind” the ObjectScope to the request.

With these things setup, we can start coding the business stuff we need. In my next post I’ll cover how to use a common abstract base class for all my entities… among other things..

Stay tuned.

Building a WCF architecture using OpenAccess – setting the scene


So it’s time for part 1 of my series on building a WCF architecture using the Telerik OpenAccess ORM as a persistence service.

Just to point it out: The series assumes that the reader has some insight into .NET development in general and how an ORM works.

The ObjectScope

Anyway let’s dive into the details. First of all some background:

When using OpenAccess to persist objects, you deal with a thing called the ObjectScope. To boil it down to the core, you can see the ObjectScope as a cache where all objects you create, fetch and change are held until they are committed. It is also the ObjectScope that handles transactions – or at least begins and commits or rollbacks them. Be aware though (I have seen a lot of misunderstandings in this area in the Telerik forums):

There’s no 1 to 1 relationship between the ObjectScope and a physical database connection

Instead, whenever an ObjectScope needs a connection (for example during queries on objects) it pulls one from the connection pool, uses it, and returns it back again. So although you might have a long-lived ObjectScope it does not have a long-lived connection to the database. That’s in general – naturally (as always) – there’s exceptions, but we won’t deal with it within the scope of this post.

Ok, enough background on the ObjectScope so far. If you need to know more go to the Telerik forums or documentation.

WCF – short

In WCF you have requests coming in from clients to a specific service method and you have responses going back to client from that service method. The general guideline when implementing services it to make them stateless. That is, they need not to know what the previous request was about – in short: They get called, perform some work, may return a result and forgets everything about it (that would be nice to do in real life, right 🙂 )

“Business transaction”

Based on several projects using WCF, I have come to the solution that in general you can consider a service method as your “business transaction”: Everything within the business workflow carried out by the service must be successful, otherwise the service method will fail. For example a service method called “CreateCustomer” might perform several steps within its workflow: Create the customer entity, call a geocoding service on the customer address, etc.. All of these steps within the main workflow (customer creation) must succeed.

Mixing my “WCF with a twist of ObjectScope” drink

With a definition like the one above we have a really good candidate location for our transaction demarcation. Start the transaction when the workflow begins and commit the transaction if all steps in the workflow succeeds, otherwise perform a rollback. The transaction I am talking about is not a database transaction. Nope, it brings us right back to the transaction managed by the ObjectScope I was starting out with.

But, to handle a transaction within OpenAccess, we need an ObjectScope. So how do we make sure that ObjectScope is always available in our services?…

WCF extensions to rescue!!

WCF has been designed from the ground to be extensible and configurable and it sure is. It has several extension points there you can plug in code to be executed. The need we have is to do something upon receiving a request and upon sending the response to that request… The place in WCF terminology to do so is called a behavior. With a behavior you can change the way the WCF pipeline handles request… There are several behavior types, but the one we’re looking for is called an endpoint behavor… and right there we will have a message inspector.

Ok, now the scene is set. In the next part of this series, I will show you how to apply all the nifty parts to make this work – all with code…

Stay tuned – I’ll be back this week

Starting out


Okey, ready to get started on a brand new blog dedicated to my profession: Software development.

Just to summarize:

Been in the business for about 14+ years, starting as a junior developer and gradually became more involved in design and architecture of software – and it’s the latter I am doing for a business right now.

So, what’s the story. I will share some great news with you. I have just been awarded a Telerik (www.telerik.com) MVP, covering their Object-Relational Mapper (ORM) called Telerik OpenAccess.

I have been using this product for about 4+ years now and uses it in a large production system. So far it works like a charm.. no issues yet.

Anyway, I will be blogging about OpenAccess and have a series of posts coming up on using OpenAccess as the persistence layer for a set of WCF services. The series will cover how you CAN build a reference WCF architecture.

So far for the first post….It’s time to start blogging

Welcome