1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 namespace System.ServiceModel.Channels
5 {
6     using System.ServiceModel.Activation;
7     using System.Collections.Generic;
8     using System.Net.Security;
9     using System.Runtime.Serialization;
10     using System.ServiceModel.Security;
11 
12     using System.Xml;
13 
14     public sealed class MsmqTransportBindingElement : MsmqBindingElementBase
15     {
16         int maxPoolSize = MsmqDefaults.MaxPoolSize;
17         bool useActiveDirectory = MsmqDefaults.UseActiveDirectory;
18         QueueTransferProtocol queueTransferProtocol = MsmqDefaults.QueueTransferProtocol;
19 
MsmqTransportBindingElement()20         public MsmqTransportBindingElement() { }
21 
MsmqTransportBindingElement(MsmqTransportBindingElement elementToBeCloned)22         MsmqTransportBindingElement(MsmqTransportBindingElement elementToBeCloned)
23             : base(elementToBeCloned)
24         {
25             this.useActiveDirectory = elementToBeCloned.useActiveDirectory;
26             this.maxPoolSize = elementToBeCloned.maxPoolSize;
27             this.queueTransferProtocol = elementToBeCloned.queueTransferProtocol;
28         }
29 
30         internal override MsmqUri.IAddressTranslator AddressTranslator
31         {
32             get
33             {
34                 switch (this.queueTransferProtocol)
35                 {
36                     case QueueTransferProtocol.Srmp:
37                         return MsmqUri.SrmpAddressTranslator;
38                     case QueueTransferProtocol.SrmpSecure:
39                         return MsmqUri.SrmpsAddressTranslator;
40                     default:
41                         return this.useActiveDirectory ? MsmqUri.ActiveDirectoryAddressTranslator : MsmqUri.NetMsmqAddressTranslator;
42                 }
43             }
44         }
45 
46         public int MaxPoolSize
47         {
48             get
49             {
50                 return this.maxPoolSize;
51             }
52             set
53             {
54                 if (value < 0)
55                 {
56                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
57                         new ArgumentOutOfRangeException("value", value, SR.GetString(SR.MsmqNonNegativeArgumentExpected)));
58                 }
59                 this.maxPoolSize = value;
60             }
61         }
62 
63         public QueueTransferProtocol QueueTransferProtocol
64         {
65             get
66             {
67                 return this.queueTransferProtocol;
68             }
69             set
70             {
71                 if (!QueueTransferProtocolHelper.IsDefined(value))
72                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
73                 this.queueTransferProtocol = value;
74             }
75         }
76 
77         public override string Scheme
78         {
79             get
80             {
81                 return "net.msmq";
82             }
83         }
84 
85         public bool UseActiveDirectory
86         {
87             get
88             {
89                 return this.useActiveDirectory;
90             }
91             set
92             {
93                 this.useActiveDirectory = value;
94             }
95         }
96 
97         internal override string WsdlTransportUri
98         {
99             get
100             {
101                 return TransportPolicyConstants.MsmqTransportUri;
102             }
103         }
104 
Clone()105         public override BindingElement Clone()
106         {
107             return new MsmqTransportBindingElement(this);
108         }
109 
CanBuildChannelFactory(BindingContext context)110         public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
111         {
112             return (typeof(TChannel) == typeof(IOutputChannel)
113                 || typeof(TChannel) == typeof(IOutputSessionChannel));
114         }
115 
CanBuildChannelListener(BindingContext context)116         public override bool CanBuildChannelListener<TChannel>(BindingContext context)
117         {
118             return (typeof(TChannel) == typeof(IInputChannel)
119                 || typeof(TChannel) == typeof(IInputSessionChannel));
120         }
121 
BuildChannelFactory(BindingContext context)122         public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
123         {
124             if (context == null)
125             {
126                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
127             }
128 
129             if (typeof(TChannel) == typeof(IOutputChannel))
130             {
131                 MsmqChannelFactoryBase<IOutputChannel> factory = new MsmqOutputChannelFactory(this, context);
132                 MsmqVerifier.VerifySender<IOutputChannel>(factory);
133                 return (IChannelFactory<TChannel>)(object)factory;
134             }
135             else if (typeof(TChannel) == typeof(IOutputSessionChannel))
136             {
137                 MsmqChannelFactoryBase<IOutputSessionChannel> factory = new MsmqOutputSessionChannelFactory(this, context);
138                 MsmqVerifier.VerifySender<IOutputSessionChannel>(factory);
139                 return (IChannelFactory<TChannel>)(object)factory;
140             }
141             else
142             {
143                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)));
144             }
145         }
146 
BuildChannelListener(BindingContext context)147         public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
148         {
149             if (context == null)
150             {
151                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
152             }
153 
154             TransportChannelListener msmqListener;
155 
156             MsmqTransportReceiveParameters receiveParameters = new MsmqTransportReceiveParameters(this, MsmqUri.NetMsmqAddressTranslator);
157 
158             if (typeof(TChannel) == typeof(IInputChannel))
159             {
160                 msmqListener = new MsmqInputChannelListener(this, context, receiveParameters);
161             }
162             else if (typeof(TChannel) == typeof(IInputSessionChannel))
163             {
164                 msmqListener = new MsmqInputSessionChannelListener(this, context, receiveParameters);
165             }
166             else
167             {
168                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)));
169             }
170             AspNetEnvironment.Current.ApplyHostedContext(msmqListener, context);
171 
172             MsmqVerifier.VerifyReceiver(receiveParameters, msmqListener.Uri);
173 
174             return (IChannelListener<TChannel>)(object)msmqListener;
175         }
176     }
177 }
178