Click here to Skip to main content
15,894,460 members
Articles / Web Development / ASP.NET

A Simple Object Collaboration Framework

Rate me:
Please Sign up or sign in to vote.
4.71/5 (7 votes)
17 Feb 2009CPOL22 min read 46.3K   189   39  
A library that simplifies complex interactions between objects by providing a new mechanism of instance discovery and lifetime management. It is an extension of the .NET CallContext or HTTPContext mechanism that provides a way of sharing objects within an execution code path.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;

namespace SOCF
{
    public class NamedCollaborationContext : IDisposable
    {
        private NamedCollaborationContext superContext;      // previously existing context that this context had to replace
        private object[] contextObjects;
        private string name;
        private bool active;      // set to true once this collaboration context object is put to context.

        public Action<NamedCollaborationContext> ContextReactivated;
        public Action<NamedCollaborationContext> ContextRevoked;
        public Action<NamedCollaborationContext> ContextDeactivated;

        public NamedCollaborationContext(string name, params object[] contextObjects)
        {
            if (name == null)
                this.name = this.GetType().FullName;
            else
                this.name = name;
            this.contextObjects = contextObjects;
            this.superContext = OverrideContext(this);
        }
        
        public string CollaborationName
        {
            get { return name; }
        }

        public NamedCollaborationContext SuperContext
        {
            get { return this.superContext; }
        }

        /// <summary>
        /// Called when this context is activated again when a nested context of same type exits its scope.
        /// </summary>
        protected virtual void OnContextReactivated()
        {
            if (ContextReactivated != null)
                ContextReactivated(this);
        }

        /// <summary>
        /// Called when the current context is overridden by a nested context.
        /// </summary>
        protected virtual void OnContextDeactivated()
        {
            if (ContextDeactivated != null)
                ContextDeactivated(this);
        }

        /// <summary>
        /// Called when the current context is disposed and revoked from call context.
        /// </summary>
        protected virtual void OnRevoke()
        {
            if (ContextRevoked != null)
                ContextRevoked(this);
        }

        /// <summary>
        /// Returns true, if this collaboration context object has been started and put to call context.
        /// </summary>
        public bool Active
        {
            get { return active; }
        }
    
        #region IDisposable Members

        public void Dispose()
        {
            RevokeContext(this);
        }

        #endregion

        private static NamedCollaborationContext OverrideContext(NamedCollaborationContext newContext)
        {
            object value = CallContextProviderModel.CallContextFactory.Instance.GetData(newContext.name);
            if (value != null && !(value is NamedCollaborationContext))
                throw new ArgumentException(string.Format("Name '{0}' specied for the CollaborationContext is already in use for another purpose!", newContext.name));
            
            NamedCollaborationContext prevContext = value as NamedCollaborationContext;
            CallContextProviderModel.CallContextFactory.Instance.SetData(newContext.name, newContext);
            newContext.active = true;
            return prevContext;
        }

        private static NamedCollaborationContext RevokeContext(NamedCollaborationContext context)
        {
            object value = CallContextProviderModel.CallContextFactory.Instance.GetData(context.name);
            if (value != null && !(value is NamedCollaborationContext))
                throw new ArgumentException(string.Format("Name '{0}' specied for the CollaborationContext is already in use for another purpose!", context.name));

            NamedCollaborationContext prevContext = value as NamedCollaborationContext;

            if (prevContext != context)
                throw new ArgumentException(string.Format("CollaborationContext '{0}' is not the immediate context!", context.name));

            context.OnRevoke();

            context.active = false;  // deactivate the context
            CallContextProviderModel.CallContextFactory.Instance.SetData(context.name, context.superContext);    // revert back to the old context.
            context.OnContextDeactivated();
            if (context.superContext != null)
            {
                context.superContext.OnContextReactivated();        // notify supercontext
            }
            return context.superContext;
        }

        public static NamedCollaborationContext Get(string name)
        {
            return CallContextProviderModel.CallContextFactory.Instance.GetData(name) as NamedCollaborationContext;
        }

        public object[] ContextObjects
        {
            get { return contextObjects; }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Netsoft-USA
United States United States
Technical Architect at Netsoft-USA. Developed Netsoft USA Framework (A software factory approach for developing object oriented + service based, data driven enterprise scale applications). Check out my new app VocaTalk Personal Podcast (A cool app that generates podcasts using Text-to-speech, background music and effects)

Comments and Discussions