CompensationParticipant.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Statements / CompensationParticipant.cs / 1305376 / CompensationParticipant.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Statements
{ 
    using System;
    using System.Collections.Generic; 
    using System.Runtime; 
    using System.Collections.ObjectModel;
 
    sealed class CompensationParticipant : NativeActivity
    {
        InArgument compensationId;
 
        Variable currentCompensationToken;
 
        public CompensationParticipant(Variable compensationId) 
            : base()
        { 
            this.compensationId = compensationId;

            this.currentCompensationToken = new Variable();
 
            DefaultCompensation = new DefaultCompensation()
                { 
                    Target = new InArgument(this.currentCompensationToken), 
                };
 
            DefaultConfirmation = new DefaultConfirmation()
                {
                    Target = new InArgument(this.currentCompensationToken),
                }; 
        }
 
        public Activity CompensationHandler 
        {
            get; 
            set;
        }

        public Activity ConfirmationHandler 
        {
            get; 
            set; 
        }
 
        public Activity CancellationHandler
        {
            get;
            set; 
        }
 
        Activity DefaultCompensation 
        {
            get; 
            set;
        }

        Activity DefaultConfirmation 
        {
            get; 
            set; 
        }
 
        protected override bool CanInduceIdle
        {
            get
            { 
                return true;
            } 
        } 

        protected override void CacheMetadata(NativeActivityMetadata metadata) 
        {
            metadata.SetImplementationVariablesCollection(
                new Collection
                { 
                    this.currentCompensationToken,
                }); 
 
            Collection children = new Collection();
 
            if (this.CompensationHandler != null)
            {
                children.Add(CompensationHandler);
            } 

            if (this.ConfirmationHandler != null) 
            { 
                children.Add(ConfirmationHandler);
            } 

            if (this.CancellationHandler != null)
            {
                children.Add(CancellationHandler); 
            }
 
            metadata.SetChildrenCollection(children); 

            Collection implementationChildren = new Collection(); 
            Fx.Assert(DefaultCompensation != null, "DefaultCompensation must be valid");
            implementationChildren.Add(DefaultCompensation);

            Fx.Assert(DefaultConfirmation != null, "DefaultConfirmation must be valid"); 
            implementationChildren.Add(DefaultConfirmation);
 
            metadata.SetImplementationChildrenCollection(implementationChildren); 

            RuntimeArgument compensationIdArgument = new RuntimeArgument("CompensationId", typeof(long), ArgumentDirection.In); 
            metadata.Bind(this.compensationId, compensationIdArgument);
            metadata.AddArgument(compensationIdArgument);
        }
 
        protected override void Execute(NativeActivityContext context)
        { 
            CompensationExtension compensationExtension = context.GetExtension(); 
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
 
            long compensationId = this.compensationId.Get(context);
            Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId passed to the SecondaryRoot must be valid");

            CompensationTokenData compensationToken = compensationExtension.Get(compensationId); 
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
 
            CompensationToken token = new CompensationToken(compensationToken); 
            this.currentCompensationToken.Set(context, token);
 
            compensationToken.IsTokenValidInSecondaryRoot = true;
            context.Properties.Add(CompensationToken.PropertyName, token);

            Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnConfirmation] == null, "Bookmark should not be already initialized in the bookmark table."); 
            compensationToken.BookmarkTable[CompensationBookmarkName.OnConfirmation] = context.CreateBookmark(new BookmarkCallback(OnConfirmation));
 
            Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnCompensation] == null, "Bookmark should not be already initialized in the bookmark table."); 
            compensationToken.BookmarkTable[CompensationBookmarkName.OnCompensation] = context.CreateBookmark(new BookmarkCallback(OnCompensation));
 
            Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnCancellation] == null, "Bookmark should not be already initialized in the bookmark table.");
            compensationToken.BookmarkTable[CompensationBookmarkName.OnCancellation] = context.CreateBookmark(new BookmarkCallback(OnCancellation));

            Bookmark onSecondaryRootScheduled = compensationToken.BookmarkTable[CompensationBookmarkName.OnSecondaryRootScheduled]; 
            Fx.Assert(onSecondaryRootScheduled != null, "onSecondaryRootScheduled bookmark must be already registered.");
 
            compensationToken.BookmarkTable[CompensationBookmarkName.OnSecondaryRootScheduled] = null; 

            context.ResumeBookmark(onSecondaryRootScheduled, compensationId); 
        }

        void OnConfirmation(NativeActivityContext context, Bookmark bookmark, object value)
        { 
            CompensationExtension compensationExtension = context.GetExtension();
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); 
 
            long compensationId = (long)value;
            Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId must be passed when resuming the Completed bookmark"); 

            CompensationTokenData compensationToken = compensationExtension.Get(compensationId);
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
 
            Fx.Assert(compensationToken.CompensationState == CompensationState.Confirming, "CompensationState should be in Confirming state");
 
            if(TD.CompensationStateIsEnabled()) 
            {
                TD.CompensationState(compensationToken.DisplayName, compensationToken.CompensationState.ToString()); 
            }

            compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCancellation);
            compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCompensation); 

            if (ConfirmationHandler != null) 
            { 
                context.ScheduleActivity(ConfirmationHandler, new CompletionCallback(OnConfirmationHandlerComplete), new FaultCallback(OnExceptionFromHandler));
            } 
            else
            {
                this.currentCompensationToken.Set(context, new CompensationToken(compensationToken));
                if (compensationToken.ExecutionTracker.Count > 0) 
                {
                    context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnConfirmationComplete)); 
                } 
                else
                { 
                    compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Confirmed);
                }
            }
        } 

        void OnConfirmationHandlerComplete(NativeActivityContext context, ActivityInstance completedInstance) 
        { 
            Fx.Assert(context != null, "context must be valid");
            Fx.Assert(completedInstance != null, "completedInstance must be valid"); 

            CompensationExtension compensationExtension = context.GetExtension();
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
 
            CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); 
 
            if (completedInstance.State == ActivityInstanceState.Closed)
            { 
                Fx.Assert(compensationToken.CompensationState == CompensationState.Confirming, "CompensationParticipant should be in Confirming State");

                this.currentCompensationToken.Set(context, new CompensationToken(compensationToken));
                if (compensationToken.ExecutionTracker.Count > 0) 
                {
                    context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnConfirmationComplete)); 
                } 
                else
                { 
                    compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Confirmed);
                }
            }
        } 

        void OnConfirmationComplete(NativeActivityContext context, ActivityInstance completedInstance) 
        { 
            Fx.Assert(context != null, "context must be valid");
            Fx.Assert(completedInstance != null, "completedInstance must be valid"); 

            CompensationExtension compensationExtension = context.GetExtension();
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
 
            CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); 
 
            if (completedInstance.State == ActivityInstanceState.Closed)
            { 
                compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Confirmed);
            }
        }
 
        void OnCompensation(NativeActivityContext context, Bookmark bookmark, object value)
        { 
            CompensationExtension compensationExtension = context.GetExtension(); 
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
 
            long compensationId = (long)value;
            Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId must be passed when resuming the Completed bookmark");

            CompensationTokenData compensationToken = compensationExtension.Get(compensationId); 
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");
 
            Fx.Assert(compensationToken.CompensationState == CompensationState.Compensating, "CompensationState should be in Compensating state"); 

            if(TD.CompensationStateIsEnabled()) 
            {
                TD.CompensationState(compensationToken.DisplayName, compensationToken.CompensationState.ToString());
            }
 
            // Cleanup Bookmarks..
            compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCancellation); 
            compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnConfirmation); 

            if (CompensationHandler != null) 
            {
                context.ScheduleActivity(CompensationHandler, new CompletionCallback(this.OnCompensationHandlerComplete), new FaultCallback(OnExceptionFromHandler));
            }
            else 
            {
                this.currentCompensationToken.Set(context, new CompensationToken(compensationToken)); 
                if (compensationToken.ExecutionTracker.Count > 0) 
                {
                    context.ScheduleActivity(DefaultCompensation, new CompletionCallback(this.OnCompensationComplete)); 
                }
                else
                {
                    this.InternalOnCompensationComplete(context, compensationExtension, compensationToken); 
                }
            } 
        } 

        void OnCompensationHandlerComplete(NativeActivityContext context, ActivityInstance completedInstance) 
        {
            Fx.Assert(context != null, "context must be valid");
            Fx.Assert(completedInstance != null, "completedInstance must be valid");
 
            CompensationExtension compensationExtension = context.GetExtension();
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); 
 
            CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context));
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); 

            if (completedInstance.State == ActivityInstanceState.Closed)
            {
                Fx.Assert(compensationToken.CompensationState == CompensationState.Compensating, "CompensationParticipant should be in Compensating State"); 

                this.currentCompensationToken.Set(context, new CompensationToken(compensationToken)); 
                if (compensationToken.ExecutionTracker.Count > 0) 
                {
                    context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnCompensationComplete)); 
                }
                else
                {
                    this.InternalOnCompensationComplete(context, compensationExtension, compensationToken); 
                }
            } 
        } 

        void OnCancellation(NativeActivityContext context, Bookmark bookmark, object value) 
        {
            CompensationExtension compensationExtension = context.GetExtension();
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid");
 
            long compensationId = (long)value;
            Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId must be passed when resuming the Completed bookmark"); 
 
            CompensationTokenData compensationToken = compensationExtension.Get(compensationId);
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); 

            Fx.Assert(compensationToken.CompensationState == CompensationState.Canceling, "CompensationState should be in Canceling state");

            if(TD.CompensationStateIsEnabled()) 
            {
                TD.CompensationState(compensationToken.DisplayName, compensationToken.CompensationState.ToString()); 
            } 

            // remove bookmarks. 
            compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCompensation);
            compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnConfirmation);

            this.currentCompensationToken.Set(context, new CompensationToken(compensationToken)); 
            if (CancellationHandler != null)
            { 
                context.ScheduleActivity(CancellationHandler, new CompletionCallback(this.OnCancellationHandlerComplete), new FaultCallback(OnExceptionFromHandler)); 
            }
            else 
            {
                if (compensationToken.ExecutionTracker.Count > 0)
                {
                    context.ScheduleActivity(DefaultCompensation, new CompletionCallback(this.OnCompensationComplete)); 
                }
                else 
                { 
                    this.InternalOnCompensationComplete(context, compensationExtension, compensationToken);
                } 
            }
        }

        void OnCancellationHandlerComplete(NativeActivityContext context, ActivityInstance completedInstance) 
        {
            CompensationExtension compensationExtension = context.GetExtension(); 
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); 

            CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context)); 
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid");

            if (completedInstance.State == ActivityInstanceState.Closed)
            { 
                Fx.Assert(compensationToken.CompensationState == CompensationState.Canceling, "CompensationParticipant should be in Canceling State");
 
                this.currentCompensationToken.Set(context, new CompensationToken(compensationToken)); 
                if (compensationToken.ExecutionTracker.Count > 0)
                { 
                    context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnCompensationComplete));
                }
                else
                { 
                    this.InternalOnCompensationComplete(context, compensationExtension, compensationToken);
                } 
            } 
        }
 
        void OnCompensationComplete(NativeActivityContext context, ActivityInstance completedInstance)
        {
            CompensationExtension compensationExtension = context.GetExtension();
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); 

            CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context)); 
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); 

            InternalOnCompensationComplete(context, compensationExtension, compensationToken); 
        }

        void InternalOnCompensationComplete(NativeActivityContext context, CompensationExtension compensationExtension, CompensationTokenData compensationToken)
        { 
            switch (compensationToken.CompensationState)
            { 
                case CompensationState.Canceling: 
                    compensationExtension.NotifyMessage(context,  compensationToken.CompensationId, CompensationBookmarkName.Canceled);
                    break; 
                case CompensationState.Compensating:
                    compensationExtension.NotifyMessage(context,  compensationToken.CompensationId, CompensationBookmarkName.Compensated);
                    break;
                default: 
                    Fx.Assert(false, "CompensationState is in unexpected state!");
                    break; 
            } 
        }
 
        void OnExceptionFromHandler(NativeActivityFaultContext context, Exception propagatedException, ActivityInstance propagatedFrom)
        {
            CompensationExtension compensationExtension = context.GetExtension();
            Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); 

            CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context)); 
            Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); 

            InvalidOperationException exception = null; 

            switch (compensationToken.CompensationState)
            {
                case CompensationState.Confirming: 
                    exception = new InvalidOperationException(SR.ConfirmationHandlerFatalException(compensationToken.DisplayName), propagatedException);
                    break; 
                case CompensationState.Compensating: 
                    exception = new InvalidOperationException(SR.CompensationHandlerFatalException(compensationToken.DisplayName), propagatedException);
                    break; 
                case CompensationState.Canceling:
                    exception = new InvalidOperationException(SR.CancellationHandlerFatalException(compensationToken.DisplayName), propagatedException);
                    break;
                default: 
                    Fx.Assert(false, "CompensationState is in unexpected state!");
                    break; 
            } 

            context.Abort(exception); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK