I'm researching what is the best way to create a generic WCF proxy wrapper
that has the following requirements:
1. Remove the System.ServiceModel config section requirement for clients. We
have our own configuration management that follows our application lifecycle
(development/system test/production). Also, most of the proxies we build are
for the middle-tier layer.
2. Create a wrapper to follow WCF Client best practices (proxy.close &
exception handling). My thought was to use the "Using" statement for
resource cleanup. (But I found another article that states otherwise : http://msdn.microsoft.com/en-us/library/ms733912.aspx)
3. In some scenarios, adjust binding security as required by an
application/service.
4. In most scenarios, we do not want to expose MEX/WSDL of the service, with
the exception of Development.
I have found numerous articles that discuss this particular topic. Based on
my knowledge of WCF, there are two ways for a client to call a WCF service...
1. Add a Service Reference.
2. Dynamically build the proxy based on the WSDL.
Basically, that leaves option 1 (due to requirement #4). With that said, I
found two different approaches of calling WCF services…
1. Use the ClientBase<TChannel>
2. Use the ChannelFactory<TChannel>
After researching the topic, I’m leaning toward option 2 and found numerous
samples on the Internet. However, I do have a question about what to cache
for performance. Most articles said to cache the proxy and reuse it as much
as possible. But, according to some articles I found, if you have to change
the binding, for example, you shouldn’t cache (Create, call, and close the
connection). Is this referring to the proxy created after calling
CreateChannel on the ChannelFactory class?
Any guidance would be most appreciated.
Thanks
--
Mark Remkiewicz
Systems Architect 5 5212
Mark,
When using ChannelBase, you're in fact calling:
- ChannelFactory.Create
- factory.CreateChannel
- ... use channel ...
- channel.Close
- factory.Close
ChannelFactory has the advantage of providing channel pooling, similar to
the known ADO connection pooling, although not exactly the same. When using
ChannelFactory, you tipically instantiate the factory once, and afterwards
keep it alive (in a static, for example), and keep on creating channels from
it. When creating the factory, you're required to provide all authentication
data required, which means that you may not change authentication elements
on channel creation.
When used in a middle tier scenario, and if the client credentials to
present downstream depend on the upstream credentials then you should also
distinguish the factories cached statically using, for example, a
dictionary. You would not want to be using a channel (with credentials
already set by its factory) that did not reflect the original upstream
credentials ...
Another thing to remember, when you close the channel, the channel goes back
to the channel pool of the factory, differently from ClientBase, where the
factory and channel are both destroyed.
avoid using the "using" keyword, since on closure (imagine an exception
occured and Dispose is called) you'll sometimes get a msg sent back and
since you already got an error on the channel and its now unusable, you're
left with an immediate exception of communication failure and you lose the
original exception. I'd avise the following channel usage:
channel c = factory createchannel()
try
{ c.method();
}
finally
{
try { c.close(); } catch { c.abort(); }
}
Finally, regarding a possible class to manage channel creation, destruction,
exception, see: http://groups.google.com/group/micro...8167ad3dd3a4e8
hope it helps
Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message
news:9A**********************************@microsof t.com...
I'm researching what is the best way to create a generic WCF proxy wrapper
that has the following requirements:
1. Remove the System.ServiceModel config section requirement for clients.
We
have our own configuration management that follows our application
lifecycle
(development/system test/production). Also, most of the proxies we build
are
for the middle-tier layer.
2. Create a wrapper to follow WCF Client best practices (proxy.close &
exception handling). My thought was to use the "Using" statement for
resource cleanup. (But I found another article that states otherwise : http://msdn.microsoft.com/en-us/library/ms733912.aspx)
3. In some scenarios, adjust binding security as required by an
application/service.
4. In most scenarios, we do not want to expose MEX/WSDL of the service,
with
the exception of Development.
I have found numerous articles that discuss this particular topic. Based
on
my knowledge of WCF, there are two ways for a client to call a WCF
service...
1. Add a Service Reference.
2. Dynamically build the proxy based on the WSDL.
Basically, that leaves option 1 (due to requirement #4). With that said,
I
found two different approaches of calling WCF services…
1. Use the ClientBase<TChannel>
2. Use the ChannelFactory<TChannel>
After researching the topic, I’m leaning toward option 2 and found
numerous
samples on the Internet. However, I do have a question about what to
cache
for performance. Most articles said to cache the proxy and reuse it as
much
as possible. But, according to some articles I found, if you have to
change
the binding, for example, you shouldn’t cache (Create, call, and close the
connection). Is this referring to the proxy created after calling
CreateChannel on the ChannelFactory class?
Any guidance would be most appreciated.
Thanks
--
Mark Remkiewicz
Systems Architect
Thanks for the reply.
Just to clarify, I should cache the factory created by CreateFactory(Of T).
If I need to pass credentials downstream, I should create a cache for each
factory based on the credentials (which makes sense).
Concerning the using statement... I wanted to create a pattern for our
developers to use. Here is a sample (This is not complete because I wanted
to have a strategy on caching the proxy):
Public MustInherit Class WcfWebServiceProxy(Of TProxy As
{WCF.ClientBase(Of TChannel), New}, TChannel As Class)
Implements IDisposable
Protected Sub New()
End Sub
Private mProxy As TChannel = Nothing
Public Sub Close()
Dim channel As WCF.ICommunicationObject = TryCast(mProxy,
WCF.ICommunicationObject)
Try
If channel IsNot Nothing Then
If channel.State <WCF.CommunicationState.Faulted Then
channel.Close()
Else
channel.Abort()
End If
End If
Catch ex As WCF.CommunicationException
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Catch ex As TimeoutException
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Catch ex As Exception
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Throw
End Try
End Sub
#Region " IDisposable Support "
Private mDisposedValue As Boolean = False ' To detect
redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not mDisposedValue Then
If disposing Then
Try
Close()
Catch
'Catch all - The error is logged
End Try
End If
End If
mDisposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the
disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal
disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
This sample was based on an article I found that I thought came close to
what you were referring to about handling the close and exception handling.
Your thoughts?
--
Mark Remkiewicz
Systems Architect
"Tiago Halm" wrote:
Mark,
When using ChannelBase, you're in fact calling:
- ChannelFactory.Create
- factory.CreateChannel
- ... use channel ...
- channel.Close
- factory.Close
ChannelFactory has the advantage of providing channel pooling, similar to
the known ADO connection pooling, although not exactly the same. When using
ChannelFactory, you tipically instantiate the factory once, and afterwards
keep it alive (in a static, for example), and keep on creating channels from
it. When creating the factory, you're required to provide all authentication
data required, which means that you may not change authentication elements
on channel creation.
When used in a middle tier scenario, and if the client credentials to
present downstream depend on the upstream credentials then you should also
distinguish the factories cached statically using, for example, a
dictionary. You would not want to be using a channel (with credentials
already set by its factory) that did not reflect the original upstream
credentials ...
Another thing to remember, when you close the channel, the channel goes back
to the channel pool of the factory, differently from ClientBase, where the
factory and channel are both destroyed.
avoid using the "using" keyword, since on closure (imagine an exception
occured and Dispose is called) you'll sometimes get a msg sent back and
since you already got an error on the channel and its now unusable, you're
left with an immediate exception of communication failure and you lose the
original exception. I'd avise the following channel usage:
channel c = factory createchannel()
try
{ c.method();
}
finally
{
try { c.close(); } catch { c.abort(); }
}
Finally, regarding a possible class to manage channel creation, destruction,
exception, see: http://groups.google.com/group/micro...8167ad3dd3a4e8
hope it helps
Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message
news:9A**********************************@microsof t.com...
I'm researching what is the best way to create a generic WCF proxy wrapper
that has the following requirements:
1. Remove the System.ServiceModel config section requirement for clients.
We
have our own configuration management that follows our application
lifecycle
(development/system test/production). Also, most of the proxies we build
are
for the middle-tier layer.
2. Create a wrapper to follow WCF Client best practices (proxy.close &
exception handling). My thought was to use the "Using" statement for
resource cleanup. (But I found another article that states otherwise : http://msdn.microsoft.com/en-us/library/ms733912.aspx)
3. In some scenarios, adjust binding security as required by an
application/service.
4. In most scenarios, we do not want to expose MEX/WSDL of the service,
with
the exception of Development.
I have found numerous articles that discuss this particular topic. Based
on
my knowledge of WCF, there are two ways for a client to call a WCF
service...
1. Add a Service Reference.
2. Dynamically build the proxy based on the WSDL.
Basically, that leaves option 1 (due to requirement #4). With that said,
I
found two different approaches of calling WCF services…
1. Use the ClientBase<TChannel>
2. Use the ChannelFactory<TChannel>
After researching the topic, I’m leaning toward option 2 and found
numerous
samples on the Internet. However, I do have a question about what to
cache
for performance. Most articles said to cache the proxy and reuse it as
much
as possible. But, according to some articles I found, if you have to
change
the binding, for example, you shouldn’t cache (Create, call, and close the
connection). Is this referring to the proxy created after calling
CreateChannel on the ChannelFactory class?
Any guidance would be most appreciated.
Thanks
--
Mark Remkiewicz
Systems Architect
The class you're writing below looks similar to the class here: http://forums.microsoft.com/MSDN/Sho...15745&SiteID=1
You're still missing the factory caching, though. The IDisposable
implementation is so the developers use the "using" statement? You then need
IDisposable to behave the same has Close (besides surpressing finalize as
you're doing).
But, doesn't it look a bit misleading to the developer? Careful so the
developer does not end up using the "using" keyword directly with a channel
and bypasses your class altogether. Its always good to let developers know
what they are dealing with and how it works.
Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message
news:CA**********************************@microsof t.com...
Thanks for the reply.
Just to clarify, I should cache the factory created by CreateFactory(Of
T).
If I need to pass credentials downstream, I should create a cache for each
factory based on the credentials (which makes sense).
Concerning the using statement... I wanted to create a pattern for our
developers to use. Here is a sample (This is not complete because I
wanted
to have a strategy on caching the proxy):
Public MustInherit Class WcfWebServiceProxy(Of TProxy As
{WCF.ClientBase(Of TChannel), New}, TChannel As Class)
Implements IDisposable
Protected Sub New()
End Sub
Private mProxy As TChannel = Nothing
Public Sub Close()
Dim channel As WCF.ICommunicationObject = TryCast(mProxy,
WCF.ICommunicationObject)
Try
If channel IsNot Nothing Then
If channel.State <WCF.CommunicationState.Faulted Then
channel.Close()
Else
channel.Abort()
End If
End If
Catch ex As WCF.CommunicationException
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Catch ex As TimeoutException
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Catch ex As Exception
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Throw
End Try
End Sub
#Region " IDisposable Support "
Private mDisposedValue As Boolean = False ' To detect
redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not mDisposedValue Then
If disposing Then
Try
Close()
Catch
'Catch all - The error is logged
End Try
End If
End If
mDisposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the
disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal
disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
This sample was based on an article I found that I thought came close to
what you were referring to about handling the close and exception
handling.
Your thoughts?
--
Mark Remkiewicz
Systems Architect
"Tiago Halm" wrote:
>Mark,
When using ChannelBase, you're in fact calling: - ChannelFactory.Create - factory.CreateChannel - ... use channel ... - channel.Close - factory.Close
ChannelFactory has the advantage of providing channel pooling, similar to the known ADO connection pooling, although not exactly the same. When using ChannelFactory, you tipically instantiate the factory once, and afterwards keep it alive (in a static, for example), and keep on creating channels from it. When creating the factory, you're required to provide all authentication data required, which means that you may not change authentication elements on channel creation.
When used in a middle tier scenario, and if the client credentials to present downstream depend on the upstream credentials then you should also distinguish the factories cached statically using, for example, a dictionary. You would not want to be using a channel (with credentials already set by its factory) that did not reflect the original upstream credentials ...
Another thing to remember, when you close the channel, the channel goes back to the channel pool of the factory, differently from ClientBase, where the factory and channel are both destroyed.
avoid using the "using" keyword, since on closure (imagine an exception occured and Dispose is called) you'll sometimes get a msg sent back and since you already got an error on the channel and its now unusable, you're left with an immediate exception of communication failure and you lose the original exception. I'd avise the following channel usage:
channel c = factory createchannel() try { c.method(); } finally { try { c.close(); } catch { c.abort(); } }
Finally, regarding a possible class to manage channel creation, destruction, exception, see: http://groups.google.com/group/micro...8167ad3dd3a4e8
hope it helps Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message news:9A**********************************@microso ft.com...
I'm researching what is the best way to create a generic WCF proxy
wrapper
that has the following requirements:
1. Remove the System.ServiceModel config section requirement for
clients.
We
have our own configuration management that follows our application
lifecycle
(development/system test/production). Also, most of the proxies we
build
are
for the middle-tier layer.
2. Create a wrapper to follow WCF Client best practices (proxy.close &
exception handling). My thought was to use the "Using" statement for
resource cleanup. (But I found another article that states otherwise : http://msdn.microsoft.com/en-us/library/ms733912.aspx)
3. In some scenarios, adjust binding security as required by an
application/service.
4. In most scenarios, we do not want to expose MEX/WSDL of the service,
with
the exception of Development.
I have found numerous articles that discuss this particular topic.
Based
on
my knowledge of WCF, there are two ways for a client to call a WCF
service...
1. Add a Service Reference.
2. Dynamically build the proxy based on the WSDL.
Basically, that leaves option 1 (due to requirement #4). With that
said,
I
found two different approaches of calling WCF services…
1. Use the ClientBase<TChannel>
2. Use the ChannelFactory<TChannel>
After researching the topic, I’m leaning toward option 2 and found
numerous
samples on the Internet. However, I do have a question about what to
cache
for performance. Most articles said to cache the proxy and reuse it as
much
as possible. But, according to some articles I found, if you have to
change
the binding, for example, you shouldn’t cache (Create, call, and close
the
connection). Is this referring to the proxy created after calling
CreateChannel on the ChannelFactory class?
Any guidance would be most appreciated.
Thanks
--
Mark Remkiewicz
Systems Architect
Yes, the sample is not complete, because I wanted to know what to cache.
This is why you are not seeing the factory cache.
If you look at "Protected Overridable Sub Dispose(ByVal disposing As
Boolean)", I call the close method. I wrap the close in this method to trap
all errors here, so exceptions are not thrown.
But, doesn't it look a bit misleading to the developer? Careful so the
developer does not end up using the "using" keyword directly with a channel
and bypasses your class altogether. Its always good to let developers know
what they are dealing with and how it works.
I'm not following the above statement. This is a base class for the
developers to inherit to create proxy wrappers, so they don't need to write
all this logic.
One other question... Your sample included a factory.close call. I don't
see that on object created from the ChannelFactory(Of T). Is there another
interface I must look at?
--
Mark Remkiewicz
Systems Architect
"Tiago Halm" wrote:
The class you're writing below looks similar to the class here: http://forums.microsoft.com/MSDN/Sho...15745&SiteID=1
You're still missing the factory caching, though. The IDisposable
implementation is so the developers use the "using" statement? You then need
IDisposable to behave the same has Close (besides surpressing finalize as
you're doing).
But, doesn't it look a bit misleading to the developer? Careful so the
developer does not end up using the "using" keyword directly with a channel
and bypasses your class altogether. Its always good to let developers know
what they are dealing with and how it works.
Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message
news:CA**********************************@microsof t.com...
Thanks for the reply.
Just to clarify, I should cache the factory created by CreateFactory(Of
T).
If I need to pass credentials downstream, I should create a cache for each
factory based on the credentials (which makes sense).
Concerning the using statement... I wanted to create a pattern for our
developers to use. Here is a sample (This is not complete because I
wanted
to have a strategy on caching the proxy):
Public MustInherit Class WcfWebServiceProxy(Of TProxy As
{WCF.ClientBase(Of TChannel), New}, TChannel As Class)
Implements IDisposable
Protected Sub New()
End Sub
Private mProxy As TChannel = Nothing
Public Sub Close()
Dim channel As WCF.ICommunicationObject = TryCast(mProxy,
WCF.ICommunicationObject)
Try
If channel IsNot Nothing Then
If channel.State <WCF.CommunicationState.Faulted Then
channel.Close()
Else
channel.Abort()
End If
End If
Catch ex As WCF.CommunicationException
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Catch ex As TimeoutException
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Catch ex As Exception
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Throw
End Try
End Sub
#Region " IDisposable Support "
Private mDisposedValue As Boolean = False ' To detect
redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not mDisposedValue Then
If disposing Then
Try
Close()
Catch
'Catch all - The error is logged
End Try
End If
End If
mDisposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the
disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal
disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
This sample was based on an article I found that I thought came close to
what you were referring to about handling the close and exception
handling.
Your thoughts?
--
Mark Remkiewicz
Systems Architect
"Tiago Halm" wrote:
Mark,
When using ChannelBase, you're in fact calling:
- ChannelFactory.Create
- factory.CreateChannel
- ... use channel ...
- channel.Close
- factory.Close
ChannelFactory has the advantage of providing channel pooling, similar to
the known ADO connection pooling, although not exactly the same. When
using
ChannelFactory, you tipically instantiate the factory once, and
afterwards
keep it alive (in a static, for example), and keep on creating channels
from
it. When creating the factory, you're required to provide all
authentication
data required, which means that you may not change authentication
elements
on channel creation.
When used in a middle tier scenario, and if the client credentials to
present downstream depend on the upstream credentials then you should
also
distinguish the factories cached statically using, for example, a
dictionary. You would not want to be using a channel (with credentials
already set by its factory) that did not reflect the original upstream
credentials ...
Another thing to remember, when you close the channel, the channel goes
back
to the channel pool of the factory, differently from ClientBase, where
the
factory and channel are both destroyed.
avoid using the "using" keyword, since on closure (imagine an exception
occured and Dispose is called) you'll sometimes get a msg sent back and
since you already got an error on the channel and its now unusable,
you're
left with an immediate exception of communication failure and you lose
the
original exception. I'd avise the following channel usage:
channel c = factory createchannel()
try
{ c.method();
}
finally
{
try { c.close(); } catch { c.abort(); }
}
Finally, regarding a possible class to manage channel creation,
destruction,
exception, see: http://groups.google.com/group/micro...8167ad3dd3a4e8
hope it helps
Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message
news:9A**********************************@microsof t.com...
I'm researching what is the best way to create a generic WCF proxy
wrapper
that has the following requirements:
1. Remove the System.ServiceModel config section requirement for
clients.
We
have our own configuration management that follows our application
lifecycle
(development/system test/production). Also, most of the proxies we
build
are
for the middle-tier layer.
2. Create a wrapper to follow WCF Client best practices (proxy.close &
exception handling). My thought was to use the "Using" statement for
resource cleanup. (But I found another article that states otherwise : http://msdn.microsoft.com/en-us/library/ms733912.aspx)
3. In some scenarios, adjust binding security as required by an
application/service.
4. In most scenarios, we do not want to expose MEX/WSDL of the service,
with
the exception of Development.
I have found numerous articles that discuss this particular topic.
Based
on
my knowledge of WCF, there are two ways for a client to call a WCF
service...
1. Add a Service Reference.
2. Dynamically build the proxy based on the WSDL.
Basically, that leaves option 1 (due to requirement #4). With that
said,
I
found two different approaches of calling WCF services…
1. Use the ClientBase<TChannel>
2. Use the ChannelFactory<TChannel>
After researching the topic, I’m leaning toward option 2 and found
numerous
samples on the Internet. However, I do have a question about what to
cache
for performance. Most articles said to cache the proxy and reuse it as
much
as possible. But, according to some articles I found, if you have to
change
the binding, for example, you shouldn’t cache (Create, call, and close
the
connection). Is this referring to the proxy created after calling
CreateChannel on the ChannelFactory class?
Any guidance would be most appreciated.
Thanks
--
Mark Remkiewicz
Systems Architect
Hi Mark,
>But, doesn't it look a bit misleading to the developer? Careful so the developer does not end up using the "using" keyword directly with a channel and bypasses your class altogether. Its always good to let developers know what they are dealing with and how it works.
I'm not following the above statement. This is a base class for the
developers to inherit to create proxy wrappers, so they don't need to
write
all this logic.
I was just emphasizing the fact that it would be useful to let developers
know, nevertheless, that using the "using" keyword with a raw channel is not
a good idea, although it is expected to be used with your channel wrapper.
One other question... Your sample included a factory.close call. I don't
see that on object created from the ChannelFactory(Of T). Is there
another
interface I must look at?
My pseudo code with "factory.close" was meant to show you what a ChannelBase
usage does. ChannelBase underneath does a factory creation, then a channel
creation, the call itself, finally a channel close and a factory close when
you close it.
The sample included in this link is in fact a wrapper for channels and makes
effetive usage of ChannelFactory. It should be easy to adapt it to your
needs - I'd see your wrapper using this class underneath for channel
management. I did use it for something similar to what you're doing. http://forums.microsoft.com/MSDN/Sho...15745&SiteID=1
Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message
news:72**********************************@microsof t.com...
Yes, the sample is not complete, because I wanted to know what to cache.
This is why you are not seeing the factory cache.
If you look at "Protected Overridable Sub Dispose(ByVal disposing As
Boolean)", I call the close method. I wrap the close in this method to
trap
all errors here, so exceptions are not thrown.
>But, doesn't it look a bit misleading to the developer? Careful so the developer does not end up using the "using" keyword directly with a channel and bypasses your class altogether. Its always good to let developers know what they are dealing with and how it works.
I'm not following the above statement. This is a base class for the
developers to inherit to create proxy wrappers, so they don't need to
write
all this logic.
One other question... Your sample included a factory.close call. I don't
see that on object created from the ChannelFactory(Of T). Is there
another
interface I must look at?
--
Mark Remkiewicz
Systems Architect
"Tiago Halm" wrote:
>The class you're writing below looks similar to the class here: http://forums.microsoft.com/MSDN/Sho...15745&SiteID=1
You're still missing the factory caching, though. The IDisposable implementation is so the developers use the "using" statement? You then need IDisposable to behave the same has Close (besides surpressing finalize as you're doing).
But, doesn't it look a bit misleading to the developer? Careful so the developer does not end up using the "using" keyword directly with a channel and bypasses your class altogether. Its always good to let developers know what they are dealing with and how it works.
Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message news:CA**********************************@microso ft.com...
Thanks for the reply.
Just to clarify, I should cache the factory created by CreateFactory(Of
T).
If I need to pass credentials downstream, I should create a cache for
each
factory based on the credentials (which makes sense).
Concerning the using statement... I wanted to create a pattern for our
developers to use. Here is a sample (This is not complete because I
wanted
to have a strategy on caching the proxy):
Public MustInherit Class WcfWebServiceProxy(Of TProxy As
{WCF.ClientBase(Of TChannel), New}, TChannel As Class)
Implements IDisposable
Protected Sub New()
End Sub
Private mProxy As TChannel = Nothing
Public Sub Close()
Dim channel As WCF.ICommunicationObject = TryCast(mProxy,
WCF.ICommunicationObject)
Try
If channel IsNot Nothing Then
If channel.State <WCF.CommunicationState.Faulted
Then
channel.Close()
Else
channel.Abort()
End If
End If
Catch ex As WCF.CommunicationException
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Catch ex As TimeoutException
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Catch ex As Exception
channel.Abort()
ExceptionPublisher.CallPublishExceptionWebService( ex)
Throw
End Try
End Sub
#Region " IDisposable Support "
Private mDisposedValue As Boolean = False ' To detect
redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not mDisposedValue Then
If disposing Then
Try
Close()
Catch
'Catch all - The error is logged
End Try
End If
End If
mDisposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the
disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in
Dispose(ByVal
disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
This sample was based on an article I found that I thought came close
to
what you were referring to about handling the close and exception
handling.
Your thoughts?
--
Mark Remkiewicz
Systems Architect
"Tiago Halm" wrote:
Mark,
When using ChannelBase, you're in fact calling: - ChannelFactory.Create - factory.CreateChannel - ... use channel ... - channel.Close - factory.Close
ChannelFactory has the advantage of providing channel pooling, similar to the known ADO connection pooling, although not exactly the same. When using ChannelFactory, you tipically instantiate the factory once, and afterwards keep it alive (in a static, for example), and keep on creating channels from it. When creating the factory, you're required to provide all authentication data required, which means that you may not change authentication elements on channel creation.
When used in a middle tier scenario, and if the client credentials to present downstream depend on the upstream credentials then you should also distinguish the factories cached statically using, for example, a dictionary. You would not want to be using a channel (with credentials already set by its factory) that did not reflect the original upstream credentials ...
Another thing to remember, when you close the channel, the channel goes back to the channel pool of the factory, differently from ClientBase, where the factory and channel are both destroyed.
avoid using the "using" keyword, since on closure (imagine an exception occured and Dispose is called) you'll sometimes get a msg sent back and since you already got an error on the channel and its now unusable, you're left with an immediate exception of communication failure and you lose the original exception. I'd avise the following channel usage:
channel c = factory createchannel() try { c.method(); } finally { try { c.close(); } catch { c.abort(); } }
Finally, regarding a possible class to manage channel creation, destruction, exception, see: http://groups.google.com/group/micro...8167ad3dd3a4e8
hope it helps Tiago Halm
"Mark" <Ma**@discussions.microsoft.comwrote in message news:9A**********************************@microso ft.com...
I'm researching what is the best way to create a generic WCF proxy
wrapper
that has the following requirements:
1. Remove the System.ServiceModel config section requirement for
clients.
We
have our own configuration management that follows our application
lifecycle
(development/system test/production). Also, most of the proxies we
build
are
for the middle-tier layer.
2. Create a wrapper to follow WCF Client best practices (proxy.close
&
exception handling). My thought was to use the "Using" statement
for
resource cleanup. (But I found another article that states otherwise
: http://msdn.microsoft.com/en-us/library/ms733912.aspx)
3. In some scenarios, adjust binding security as required by an
application/service.
4. In most scenarios, we do not want to expose MEX/WSDL of the
service,
with
the exception of Development.
I have found numerous articles that discuss this particular topic.
Based
on
my knowledge of WCF, there are two ways for a client to call a WCF
service...
1. Add a Service Reference.
2. Dynamically build the proxy based on the WSDL.
Basically, that leaves option 1 (due to requirement #4). With that
said,
I
found two different approaches of calling WCF services…
1. Use the ClientBase<TChannel>
2. Use the ChannelFactory<TChannel>
After researching the topic, I’m leaning toward option 2 and found
numerous
samples on the Internet. However, I do have a question about what
to
cache
for performance. Most articles said to cache the proxy and reuse it
as
much
as possible. But, according to some articles I found, if you have
to
change
the binding, for example, you shouldn’t cache (Create, call, and
close
the
connection). Is this referring to the proxy created after calling
CreateChannel on the ChannelFactory class?
Any guidance would be most appreciated.
Thanks
--
Mark Remkiewicz
Systems Architect This discussion thread is closed Replies have been disabled for this discussion. Similar topics
reply
views
Thread by Abhishek Srivastava |
last post: by
|
3 posts
views
Thread by Søren Reinke |
last post: by
|
7 posts
views
Thread by Nalaka |
last post: by
|
8 posts
views
Thread by A.M-SG |
last post: by
|
reply
views
Thread by John |
last post: by
|
1 post
views
Thread by khubieb |
last post: by
|
3 posts
views
Thread by =?Utf-8?B?RGFuaWVs?= |
last post: by
|
2 posts
views
Thread by Doken13 |
last post: by
|
5 posts
views
Thread by =?Utf-8?B?TWFyaw==?= |
last post: by
| | | | | | | | | | |