File: System\ServiceModel\Dispatcher\DispatchRuntime.cs
Project: ndp\cdf\src\WCF\ServiceModel\System.ServiceModel.csproj (System.ServiceModel)
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
 
namespace System.ServiceModel.Dispatcher
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.IdentityModel.Policy;
    using System.Runtime;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    using System.ServiceModel.Diagnostics;
    using System.Threading;
    using System.Web.Security;
    using System.Runtime.Diagnostics;
 
    public sealed class DispatchRuntime
    {
        ServiceAuthenticationManager serviceAuthenticationManager;
        ServiceAuthorizationManager serviceAuthorizationManager;
        ReadOnlyCollection<IAuthorizationPolicy> externalAuthorizationPolicies;
        AuditLogLocation securityAuditLogLocation;
        ConcurrencyMode concurrencyMode;
        bool ensureOrderedDispatch;
        bool suppressAuditFailure;
        AuditLevel serviceAuthorizationAuditLevel;
        AuditLevel messageAuthenticationAuditLevel;
        bool automaticInputSessionShutdown;
        ChannelDispatcher channelDispatcher;
        SynchronizedCollection<IInputSessionShutdown> inputSessionShutdownHandlers;
        EndpointDispatcher endpointDispatcher;
        IInstanceProvider instanceProvider;
        IInstanceContextProvider instanceContextProvider;
        InstanceContext singleton;
        bool ignoreTransactionMessageProperty;
        SynchronizedCollection<IDispatchMessageInspector> messageInspectors;
        OperationCollection operations;
        IDispatchOperationSelector operationSelector;
        ClientRuntime proxyRuntime;
        ImmutableDispatchRuntime runtime;
        SynchronizedCollection<IInstanceContextInitializer> instanceContextInitializers;
        bool isExternalPoliciesSet;
        bool isAuthenticationManagerSet;
        bool isAuthorizationManagerSet;
        SynchronizationContext synchronizationContext;
        PrincipalPermissionMode principalPermissionMode;
        object roleProvider;
        Type type;
        DispatchOperation unhandled;
        bool transactionAutoCompleteOnSessionClose;
        bool impersonateCallerForAllOperations;
        bool impersonateOnSerializingReply;
        bool releaseServiceInstanceOnTransactionComplete;
        SharedRuntimeState shared;
        bool preserveMessage;
        bool requireClaimsPrincipalOnOperationContext;
 
        internal DispatchRuntime(EndpointDispatcher endpointDispatcher)
            : this(new SharedRuntimeState(true))
        {
            if (endpointDispatcher == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointDispatcher");
            }
 
            this.endpointDispatcher = endpointDispatcher;
 
            Fx.Assert(shared.IsOnServer, "Server constructor called on client?");
        }
 
        internal DispatchRuntime(ClientRuntime proxyRuntime, SharedRuntimeState shared)
            : this(shared)
        {
            if (proxyRuntime == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("proxyRuntime");
            }
 
            this.proxyRuntime = proxyRuntime;
            this.instanceProvider = new CallbackInstanceProvider();
            this.channelDispatcher = new ChannelDispatcher(shared);
            this.instanceContextProvider = InstanceContextProviderBase.GetProviderForMode(InstanceContextMode.PerSession, this);
 
            Fx.Assert(!shared.IsOnServer, "Client constructor called on server?");
        }
 
        DispatchRuntime(SharedRuntimeState shared)
        {
            this.shared = shared;
 
            this.operations = new OperationCollection(this);
 
            this.inputSessionShutdownHandlers = this.NewBehaviorCollection<IInputSessionShutdown>();
            this.messageInspectors = this.NewBehaviorCollection<IDispatchMessageInspector>();
            this.instanceContextInitializers = this.NewBehaviorCollection<IInstanceContextInitializer>();
            this.synchronizationContext = ThreadBehavior.GetCurrentSynchronizationContext();
 
            this.automaticInputSessionShutdown = true;
            this.principalPermissionMode = ServiceAuthorizationBehavior.DefaultPrincipalPermissionMode;
 
            this.securityAuditLogLocation = ServiceSecurityAuditBehavior.defaultAuditLogLocation;
            this.suppressAuditFailure = ServiceSecurityAuditBehavior.defaultSuppressAuditFailure;
            this.serviceAuthorizationAuditLevel = ServiceSecurityAuditBehavior.defaultServiceAuthorizationAuditLevel;
            this.messageAuthenticationAuditLevel = ServiceSecurityAuditBehavior.defaultMessageAuthenticationAuditLevel;
 
            this.unhandled = new DispatchOperation(this, "*", MessageHeaders.WildcardAction, MessageHeaders.WildcardAction);
            this.unhandled.InternalFormatter = MessageOperationFormatter.Instance;
            this.unhandled.InternalInvoker = new UnhandledActionInvoker(this);
        }
 
        public IInstanceContextProvider InstanceContextProvider
        {
            get
            {
                return this.instanceContextProvider;
            }
 
            set
            {
                if (value == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
                }
 
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.instanceContextProvider = value;
                }
            }
        }
 
        public InstanceContext SingletonInstanceContext
        {
            get { return this.singleton; }
            set
            {
                if (value == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
                }
 
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.singleton = value;
                }
            }
        }
 
        public ConcurrencyMode ConcurrencyMode
        {
            get
            {
                return this.concurrencyMode;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.concurrencyMode = value;
                }
            }
        }
 
        public bool EnsureOrderedDispatch
        {
            get
            {
                return this.ensureOrderedDispatch;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.ensureOrderedDispatch = value;
                }
            }
        }
 
        public AuditLogLocation SecurityAuditLogLocation
        {
            get
            {
                return this.securityAuditLogLocation;
            }
            set
            {
                if (!AuditLogLocationHelper.IsDefined(value))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
                }
 
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.securityAuditLogLocation = value;
                }
            }
        }
 
        public bool SuppressAuditFailure
        {
            get
            {
                return this.suppressAuditFailure;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.suppressAuditFailure = value;
                }
            }
        }
 
        public AuditLevel ServiceAuthorizationAuditLevel
        {
            get
            {
                return this.serviceAuthorizationAuditLevel;
            }
            set
            {
                if (!AuditLevelHelper.IsDefined(value))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
                }
 
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.serviceAuthorizationAuditLevel = value;
                }
            }
        }
 
        public AuditLevel MessageAuthenticationAuditLevel
        {
            get
            {
                return this.messageAuthenticationAuditLevel;
            }
            set
            {
                if (!AuditLevelHelper.IsDefined(value))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
                }
 
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.messageAuthenticationAuditLevel = value;
                }
            }
        }
 
        public ReadOnlyCollection<IAuthorizationPolicy> ExternalAuthorizationPolicies
        {
            get
            {
                return this.externalAuthorizationPolicies;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.externalAuthorizationPolicies = value;
                    this.isExternalPoliciesSet = true;
                }
            }
        }
 
        public ServiceAuthenticationManager ServiceAuthenticationManager
        {
            get
            {
                return this.serviceAuthenticationManager;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.serviceAuthenticationManager = value;
                    this.isAuthenticationManagerSet = true;
                }
            }
        }
 
        public ServiceAuthorizationManager ServiceAuthorizationManager
        {
            get
            {
                return this.serviceAuthorizationManager;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.serviceAuthorizationManager = value;
                    this.isAuthorizationManagerSet = true;
                }
            }
        }
 
        public bool AutomaticInputSessionShutdown
        {
            get { return this.automaticInputSessionShutdown; }        
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.automaticInputSessionShutdown = value;
                }
            }
        }
 
        public ChannelDispatcher ChannelDispatcher
        {
            get { return this.channelDispatcher ?? this.endpointDispatcher.ChannelDispatcher; }
        }
 
        public ClientRuntime CallbackClientRuntime
        {
            get
            {
                if (this.proxyRuntime == null)
                {
                    lock (this.ThisLock)
                    {
                        if (this.proxyRuntime == null)
                        {
                            this.proxyRuntime = new ClientRuntime(this, this.shared);
                        }
                    }
                }
 
                return this.proxyRuntime;
            }
        }
 
        public EndpointDispatcher EndpointDispatcher
        {
            get { return this.endpointDispatcher; }
        }
 
        public bool ImpersonateCallerForAllOperations
        {
            get
            {
                return this.impersonateCallerForAllOperations;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.impersonateCallerForAllOperations = value;
                }
            }
        }
 
        public bool ImpersonateOnSerializingReply
        {
            get
            {
                return this.impersonateOnSerializingReply;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.impersonateOnSerializingReply = value;
                }
            }
        }
 
        internal bool RequireClaimsPrincipalOnOperationContext
        {
            get
            {
                return this.requireClaimsPrincipalOnOperationContext;
            }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.requireClaimsPrincipalOnOperationContext = value;
                }
            }
        }
 
        public SynchronizedCollection<IInputSessionShutdown> InputSessionShutdownHandlers
        {
            get { return this.inputSessionShutdownHandlers; }
        }
 
        public bool IgnoreTransactionMessageProperty
        {
            get { return this.ignoreTransactionMessageProperty; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.ignoreTransactionMessageProperty = value;
                }
            }
        }
 
        public IInstanceProvider InstanceProvider
        {
            get { return this.instanceProvider; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.instanceProvider = value;
                }
            }
        }
 
        public SynchronizedCollection<IDispatchMessageInspector> MessageInspectors
        {
            get { return this.messageInspectors; }
        }
 
        public SynchronizedKeyedCollection<string, DispatchOperation> Operations
        {
            get { return this.operations; }
        }
 
        public IDispatchOperationSelector OperationSelector
        {
            get { return this.operationSelector; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.operationSelector = value;
                }
            }
        }
 
        public bool ReleaseServiceInstanceOnTransactionComplete
        {
            get { return this.releaseServiceInstanceOnTransactionComplete; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.releaseServiceInstanceOnTransactionComplete = value;
                }
            }
        }       
 
        public SynchronizedCollection<IInstanceContextInitializer> InstanceContextInitializers
        {
            get { return this.instanceContextInitializers; }
        }
 
        public SynchronizationContext SynchronizationContext
        {
            get { return this.synchronizationContext; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.synchronizationContext = value;
                }
            }
        }
 
        public PrincipalPermissionMode PrincipalPermissionMode
        {
            get
            {
                return this.principalPermissionMode;
            }
            set
            {
                if (!PrincipalPermissionModeHelper.IsDefined(value))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
                }
 
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.principalPermissionMode = value;
                }
            }
        }
 
        public RoleProvider RoleProvider
        {
            get { return (RoleProvider)this.roleProvider; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.roleProvider = value;
                }
            }
        }
 
        public bool TransactionAutoCompleteOnSessionClose
        {
            get { return this.transactionAutoCompleteOnSessionClose; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.transactionAutoCompleteOnSessionClose = value;
                }
            }
        }
 
        public Type Type
        {
            get { return this.type; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.type = value;
                }
            }
        }
 
        public DispatchOperation UnhandledDispatchOperation
        {
            get { return this.unhandled; }
            set
            {
                if (value == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
                }
 
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.unhandled = value;
                }
            }
        }
 
        public bool ValidateMustUnderstand
        {
            get { return this.shared.ValidateMustUnderstand; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.shared.ValidateMustUnderstand = value;
                }
            }
        }
 
        public bool PreserveMessage
        {
            get { return this.preserveMessage; }
            set
            {
                lock (this.ThisLock)
                {
                    this.InvalidateRuntime();
                    this.preserveMessage = value;
                }
            }
        }
 
        internal bool RequiresAuthentication
        {
            get
            {
                return this.isAuthenticationManagerSet;
            }
        }
 
        internal bool RequiresAuthorization
        {
            get
            {
                return (this.isAuthorizationManagerSet || this.isExternalPoliciesSet ||
                    AuditLevel.Success == (this.serviceAuthorizationAuditLevel & AuditLevel.Success));
            }
        }
 
        internal bool HasMatchAllOperation
        {
            get
            {
                lock (this.ThisLock)
                {
                    return !(this.unhandled.Invoker is UnhandledActionInvoker);
                }
            }
        }
 
        internal bool EnableFaults
        {
            get
            {
                if (this.IsOnServer)
                {
                    ChannelDispatcher channelDispatcher = this.ChannelDispatcher;
                    return (channelDispatcher != null) && channelDispatcher.EnableFaults;
                }
                else
                {
                    return this.shared.EnableFaults;
                }
            }
        }
 
        internal bool IsOnServer
        {
            get { return this.shared.IsOnServer; }
        }
 
        internal bool ManualAddressing
        {
            get
            {
                if (this.IsOnServer)
                {
                    ChannelDispatcher channelDispatcher = this.ChannelDispatcher;
                    return (channelDispatcher != null) && channelDispatcher.ManualAddressing;
                }
                else
                {
                    return this.shared.ManualAddressing;
                }
            }
        }
 
        internal int MaxCallContextInitializers
        {
            get
            {
                lock (this.ThisLock)
                {
                    int max = 0;
 
                    for (int i = 0; i < this.operations.Count; i++)
                    {
                        max = System.Math.Max(max, this.operations[i].CallContextInitializers.Count);
                    }
                    max = System.Math.Max(max, this.unhandled.CallContextInitializers.Count);
                    return max;
                }
            }
        }
 
        internal int MaxParameterInspectors
        {
            get
            {
                lock (this.ThisLock)
                {
                    int max = 0;
 
                    for (int i = 0; i < this.operations.Count; i++)
                    {
                        max = System.Math.Max(max, this.operations[i].ParameterInspectors.Count);
                    }
                    max = System.Math.Max(max, this.unhandled.ParameterInspectors.Count);
                    return max;
                }
            }
        }
 
        // Internal access to CallbackClientRuntime, but this one doesn't create on demand
        internal ClientRuntime ClientRuntime
        {
            get { return this.proxyRuntime; }
        }
 
        internal object ThisLock
        {
            get { return this.shared; }
        }
 
        internal bool IsRoleProviderSet
        {
            get { return this.roleProvider != null; }
        }
 
        internal DispatchOperationRuntime GetOperation(ref Message message)
        {
            ImmutableDispatchRuntime runtime = this.GetRuntime();
            return runtime.GetOperation(ref message);
        }
 
        internal ImmutableDispatchRuntime GetRuntime()
        {
            ImmutableDispatchRuntime runtime = this.runtime;
            if (runtime != null)
            {
                return runtime;
            }
            else
            {
                return GetRuntimeCore();
            }
        }
 
        ImmutableDispatchRuntime GetRuntimeCore()
        {
            lock (this.ThisLock)
            {
                if (this.runtime == null)
                {
                    this.runtime = new ImmutableDispatchRuntime(this);
                }
 
                return this.runtime;
            }
        }
 
        internal void InvalidateRuntime()
        {
            lock (this.ThisLock)
            {
                this.shared.ThrowIfImmutable();
                this.runtime = null;
            }
        }
 
        internal void LockDownProperties()
        {
            this.shared.LockDownProperties();
            if (this.concurrencyMode != ConcurrencyMode.Single && this.ensureOrderedDispatch)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxDispatchRuntimeNonConcurrentOrEnsureOrderedDispatch)));
            }
        }
 
        internal SynchronizedCollection<T> NewBehaviorCollection<T>()
        {
            return new DispatchBehaviorCollection<T>(this);
        }
 
        internal void SetDebugFlagInDispatchOperations(bool includeExceptionDetailInFaults)
        {
            foreach (DispatchOperation dispatchOperation in this.operations)
            {
                dispatchOperation.IncludeExceptionDetailInFaults = includeExceptionDetailInFaults;
            }
        }
 
        internal class UnhandledActionInvoker : IOperationInvoker
        {
            DispatchRuntime dispatchRuntime;
 
            public UnhandledActionInvoker(DispatchRuntime dispatchRuntime)
            {
                this.dispatchRuntime = dispatchRuntime;
            }
 
            public bool IsSynchronous
            {
                get { return true; }
            }
 
            public object[] AllocateInputs()
            {
                return new object[1];
            }
 
            public object Invoke(object instance, object[] inputs, out object[] outputs)
            {
                outputs = EmptyArray<object>.Allocate(0);
 
                Message message = inputs[0] as Message;
                if (message == null)
                {
                    return null;
                }
 
                string action = message.Headers.Action;
 
                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.UnhandledAction,
                        SR.GetString(SR.TraceCodeUnhandledAction),
                        new StringTraceRecord("Action", action),
                        this, null, message);
                }
 
                FaultCode code = FaultCode.CreateSenderFaultCode(AddressingStrings.ActionNotSupported,
                    message.Version.Addressing.Namespace);
                string reasonText = SR.GetString(SR.SFxNoEndpointMatchingContract, action);
                FaultReason reason = new FaultReason(reasonText);
 
                FaultException exception = new FaultException(reason, code);
                ErrorBehavior.ThrowAndCatch(exception);
 
                ServiceChannel serviceChannel = OperationContext.Current.InternalServiceChannel;
                OperationContext.Current.OperationCompleted += 
                    delegate(object sender, EventArgs e) 
                {
                    ChannelDispatcher channelDispatcher = this.dispatchRuntime.ChannelDispatcher;
                    if (!channelDispatcher.HandleError(exception) && serviceChannel.HasSession)
                    {
                        try
                        {
                            serviceChannel.Close(ChannelHandler.CloseAfterFaultTimeout); 
                        }
                        catch (Exception ex)
                        {
                            if (Fx.IsFatal(ex))
                            {
                                throw;
                            }
                            channelDispatcher.HandleError(ex);
                        }
                    }
                };
 
                if (this.dispatchRuntime.shared.EnableFaults)
                {
                    MessageFault fault = MessageFault.CreateFault(code, reason, action);
                    return Message.CreateMessage(message.Version, fault, message.Version.Addressing.DefaultFaultAction);
                }
                else
                {
                    OperationContext.Current.RequestContext.Close();
                    OperationContext.Current.RequestContext = null;
                    return null;
                }
            }
 
            public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
            }
 
            public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
            }
        }
 
        class DispatchBehaviorCollection<T> : SynchronizedCollection<T>
        {
            DispatchRuntime outer;
 
            internal DispatchBehaviorCollection(DispatchRuntime outer)
                : base(outer.ThisLock)
            {
                this.outer = outer;
            }
 
            protected override void ClearItems()
            {
                this.outer.InvalidateRuntime();
                base.ClearItems();
            }
 
            protected override void InsertItem(int index, T item)
            {
                if (item == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
                }
 
                this.outer.InvalidateRuntime();
                base.InsertItem(index, item);
            }
 
            protected override void RemoveItem(int index)
            {
                this.outer.InvalidateRuntime();
                base.RemoveItem(index);
            }
 
            protected override void SetItem(int index, T item)
            {
                if (item == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
                }
 
                this.outer.InvalidateRuntime();
                base.SetItem(index, item);
            }
        }
 
        class OperationCollection : SynchronizedKeyedCollection<string, DispatchOperation>
        {
            DispatchRuntime outer;
 
            internal OperationCollection(DispatchRuntime outer)
                : base(outer.ThisLock)
            {
                this.outer = outer;
            }
 
            protected override void ClearItems()
            {
                this.outer.InvalidateRuntime();
                base.ClearItems();
            }
 
            protected override string GetKeyForItem(DispatchOperation item)
            {
                return item.Name;
            }
 
            protected override void InsertItem(int index, DispatchOperation item)
            {
                if (item == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
                }
                if (item.Parent != this.outer)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxMismatchedOperationParent));
                }
 
                this.outer.InvalidateRuntime();
                base.InsertItem(index, item);
            }
 
            protected override void RemoveItem(int index)
            {
                this.outer.InvalidateRuntime();
                base.RemoveItem(index);
            }
 
            protected override void SetItem(int index, DispatchOperation item)
            {
                if (item == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
                }
                if (item.Parent != this.outer)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxMismatchedOperationParent));
                }
 
                this.outer.InvalidateRuntime();
                base.SetItem(index, item);
            }
        }
 
        class CallbackInstanceProvider : IInstanceProvider
        {
            object IInstanceProvider.GetInstance(InstanceContext instanceContext)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCannotActivateCallbackInstace)));
            }
 
            object IInstanceProvider.GetInstance(InstanceContext instanceContext, Message message)
            {
                throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCannotActivateCallbackInstace)), message);
            }
 
            void IInstanceProvider.ReleaseInstance(InstanceContext instanceContext, object instance)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCannotActivateCallbackInstace)));
            }
        }
    }
}