• WCF服务编程读书笔记(5):操作


    Example 5-1. Defining and configuring a callback contract

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Diagnostics;
    using System.Runtime.Serialization;
    
    namespace WCFServiceProgramming.Library
    {
        public interface ISomeCallbackContract
        {
            [OperationContract]
            void OnCallback();
        }
    
        [ServiceContract(CallbackContract = typeof(ISomeCallbackContract))]
        public interface IMyContract
        {
            [OperationContract]
            void DoSomething();
        }
    }
    View Code

    Example 5-2. The DuplexClientBase<T> class

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    
    namespace WCFServiceProgramming
    {
        public interface IDuplexContextChannel : IContextChannel
        {
            InstanceContext CallbackInstance
            {
                get;
                set;
            }
    
            //...
        }
    
        public abstract class DuplexClientBase<T> : ClientBase<T> where T : class
        {
            protected DuplexClientBase(InstanceContext callbackContext);
            protected DuplexClientBase(InstanceContext callbackContext, string endpointName);
            protected DuplexClientBase(InstanceContext callbackContext, 
                Binding binding, 
                EndpointAddress remoteAddress);
    
            protected DuplexClientBase(object callbackInstance);
            protected DuplexClientBase(object callbackInstance, string endpointConfiguratinName);
            protected DuplexClientBase(object callbackInstance, 
                Binding binding, 
                EndpointAddress remoteAddress);
    
            public IDuplexContextChannel InnerDuplexChannel
            {
                get;
            }
    
            //...
        }
    }
    View Code

    Example 5-3. Tool-generated duplex proxy

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using WCFServiceProgramming.Library;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    
    namespace WCFServiceProgramming
    {
        class MyContractClient : DuplexClientBase<IMyContract>, IMyContract
        {
            public MyContractClient(InstanceContext callbackContext) : base(callbackContext) { }
            public MyContractClient(InstanceContext callbackContext, string endpointName) :
                base(callbackContext, endpointName) { }
            public MyContractClient(InstanceContext callbackContext, Binding binding,
                EndpointAddress remoteAddress) :
                base(callbackContext, binding, remoteAddress) { }
    
            public void DoSomething()
            {
                Channel.DoSomething();
            }
        }
    }
    View Code

    Example 5-4. Client implementing the callback contract

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using WCFServiceProgramming.Library;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming
    {
        class MyClient : IMyContractCallback, IDisposable
        {
            MyContractClient m_Proxy;
    
            public void CallService()
            {
                InstanceContext context = new InstanceContext(this);
    
                m_Proxy = new MyContractClient(context);
                m_Proxy.DoSomething();
            }
    
            public void OnCallback()
            { 
                //...
            }
    
            public void Dispose()
            {
                m_Proxy.Close();
            }
        }
    }
    View Code

    Example 5-5. Using a reworked object-based proxy

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using WCFServiceProgramming.Library;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming
    {
        class MyContractClient : DuplexClientBase<IMyContract>, IMyContract
        {
            public MyContractClient(object callbackInstance)
                : base(callbackInstance)
            { }
    
            public void DoSomething()
            {
                Channel.DoSomething();
            }
        }
    
        class MyClient : IMyContractCallback, IDisposable
        {
            MyContractClient m_Proxy;
    
            public void CallService()
            {
                m_Proxy = new MyContractClient(this);
                m_Proxy.DoSomething();
            }
    
            public void OnCallback()
            { 
                //...
            }
    
            public void Dispose()
            {
                m_Proxy.Close();
            }
        }
    }
    View Code

    Example 5-6. Storing the callback references for later use

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Diagnostics;
    using System.Runtime.Serialization;
    
    namespace WCFServiceProgramming.Library
    {
        public interface ISomeCallbackContract
        {
            [OperationContract]
            void OnCallback();
        }
    
        [ServiceContract]
        public interface IMyContract
        {
            [OperationContract]
            void DoSomething();
        }
    
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
        class MyService : IMyContract
        {
            static List<ISomeCallbackContract> m_Callbacks = new List<ISomeCallbackContract>();
    
            public void DoSomething()
            {
                ISomeCallbackContract callback = 
                    OperationContext.Current.GetCallbackChannel<ISomeCallbackContract>();
    
                if (m_Callbacks.Contains(callback) == false)
                {
                    m_Callbacks.Add(callback);
                }
            }
    
            public static void CallClients()
            {
                Action<ISomeCallbackContract> invoke = delegate(ISomeCallbackContract callback)
                {
                    callback.OnCallback();
                };
    
                m_Callbacks.ForEach(invoke);
            }
        }
    
    }
    View Code

    Example 5-7. Configure for reentrancy to allow callbacks

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Diagnostics;
    using System.Runtime.Serialization;
    
    namespace WCFServiceProgramming.Library
    {
        public interface IMyContractCallback
        {
            [OperationContract]
            void OnCallback();
        }
    
        [ServiceContract(CallbackContract = typeof(IMyContractCallback))]
        public interface IMyContract
        {
            [OperationContract]
            void DoSomething();
        }
    
        [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
        class MyService : IMyContract
        {
            public void DoSomething()
            {
                IMyContractCallback callback = 
                    OperationContext.Current.GetCallbackChannel<IMyContractCallback>();
                callback.OnCallback();
            }
        }
    }
    View Code

    Example 5-8. One-way callbacks are allowed by default

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Diagnostics;
    using System.Runtime.Serialization;
    
    namespace WCFServiceProgramming.Library
    {
        public interface IMyContractCallback
        {
            [OperationContract(IsOneWay = true)]
            void OnCallback();
        }
    
        [ServiceContract(CallbackContract = typeof(IMyContractCallback))]
        public interface IMyContract
        {
            [OperationContract]
            void DoSomething();
        }
    
        [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
        class MyService : IMyContract
        {
            public void DoSomething()
            {
                IMyContractCallback callback = 
                    OperationContext.Current.GetCallbackChannel<IMyContractCallback>();
                callback.OnCallback();
            }
        }
    }
    View Code

    Example 5-9. Explicit callback connection management 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.Transactions;
    using System.Diagnostics;
    
    namespace WCFServiceProgramming.Library
    {
        [ServiceContract(CallbackContract = typeof(IMyContractCallback))]
        interface IMyContract
        {
            [OperationContract]
            void MyMethod();
    
            [OperationContract]
            void Connect();
    
            [OperationContract]
            void Disconnect();
        }
    
        interface IMyContractCallback
        {
            [OperationContract]
            void OnCallback();
        }
    
        class MyService : IMyContract
        {
            static List<IMyContractCallback> _callbacks = new List<IMyContractCallback>();
    
            public void Connect()
            {
                IMyContractCallback callback = 
                    OperationContext.Current.GetCallbackChannel<IMyContractCallback>();
    
                if (_callbacks.Contains(callback) == false)
                {
                    _callbacks.Add(callback);
                }
            }
    
            public void Disconnect()
            {
                IMyContractCallback callback =
                    OperationContext.Current.GetCallbackChannel<IMyContractCallback>();
    
                if (_callbacks.Contains(callback) == true)
                {
                    _callbacks.Remove(callback);
                }
                else
                {
                    throw new InvalidOperationException("Cannot find callback");
                }
            }
    
            public static void CallClients()
            {
                Action<IMyContractCallback> invoke = delegate(IMyContractCallback callback)
                {
                    callback.OnCallback();
                };
    
                _callbacks.ForEach(invoke);
            }
    
            public void MyMethod()
            {
            }
        }
    }
    View Code

    Example 5-10. The InstanceContext<T> class

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming.Library
    {
        public class InstanceContext<T>
        {
            InstanceContext _instanceContext;
    
            public InstanceContext(T implementation)
            {
                _instanceContext = new InstanceContext(implementation);
            }
    
            public InstanceContext Context
            {
                get
                {
                    return _instanceContext;
                }
            }
    
            public T ServiceInstance
            {
                get
                {
                    return (T)_instanceContext.GetServiceInstance();
                }
            }
        }
    }
    View Code

    Example 5-11. TheDuplexClientBase<T,C>class

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using WCFServiceProgramming.Library;
    
    namespace WCFServiceProgramming
    {
        public abstract class DuplexClientBase<T, C> : DuplexClientBase<T> where T : class
        {
            protected DuplexClientBase(InstanceContext<C> context) : base(context.Context)
            {}
    
            protected DuplexClientBase(InstanceContext<C> context,
                string endpointName) : base(context.Context, endpointName)
            {}
    
            protected DuplexClientBase(InstanceContext<C> context,
                Binding binding, EndpointAddress remoteAddress) : 
                base(context.Context, binding, remoteAddress)
            {}
    
            protected DuplexClientBase(C callback) : base(callback)
            {}
    
            protected DuplexClientBase(C callback, string endpointName) :
                base(callback,endpointName)
            {}
    
            protected DuplexClientBase(C callback, Binding binding,
                EndpointAddress remoteAddress) :
                base(callback,binding, remoteAddress)
            { }
    
            static DuplexClientBase()
            {
                VerifyCallback();
            }
    
            internal static void VerifyCallback()
            {
                Type contractType = typeof(T);
                Type callbackType = typeof(C);
                object[] attributes = contractType.GetCustomAttributes(
                typeof(ServiceContractAttribute), false);
    
                if (attributes.Length != 1)
                {
                    throw new InvalidOperationException("Type of " + contractType +
                    " is not a service contract");
                }
    
                ServiceContractAttribute serviceContractAttribute;
                serviceContractAttribute = attributes[0] as ServiceContractAttribute;
    
                if (callbackType != serviceContractAttribute.CallbackContract)
                {
                    throw new InvalidOperationException("Type of " + callbackType +
                    " is not configured as callback contract for " + contractType);
                }
            }
        }
    
        public abstract class DuplexClientBase<T> : ClientBase<T> where T : class
        {
            protected DuplexClientBase(InstanceContext callbackContext);
            protected DuplexClientBase(InstanceContext callbackContext, string endpointName);
            protected DuplexClientBase(InstanceContext callbackContext, 
                Binding binding, 
                EndpointAddress remoteAddress);
    
            protected DuplexClientBase(object callbackInstance);
            protected DuplexClientBase(object callbackInstance, string endpointConfiguratinName);
            protected DuplexClientBase(object callbackInstance, 
                Binding binding, 
                EndpointAddress remoteAddress);
    
            public IDuplexContextChannel InnerDuplexChannel
            {
                get;
            }
        }
    
        public interface IDuplexContextChannel : IContextChannel
        {
            InstanceContext CallbackInstance
            {
                get;
                set;
            }
        }
    }
    View Code

    Example 5-12. The DuplexChannelFactory<T,C> class

    Example 5-13. Adding duplex support to InProcFactory

    Example 5-14. The WsDualProxyHelper class

    Example 5-15. The CallbackBaseAddressBehaviorAttribute

    Example 5-16. Events management using delegates

    Example 5-17. Streaming operations

  • 相关阅读:
    MAVEN[08]
    MAVEN[04]
    hdu 1757【A Simple Math Problem】
    hdu 1507【Uncle Tom's Inherited Land*】
    hdu 2768【Cat vs. Dog】
    hdu 1392【Surround the Trees】
    hdu 1348【wall】
    hdu 2824【The Euler function】
    hdu 1147【Pickup sticks】
    hdu 1528【Card Game Cheater】
  • 原文地址:https://www.cnblogs.com/thlzhf/p/2783002.html
Copyright © 2020-2023  润新知