473,405 Members | 2,415 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

WCF Client Proxy and caching...

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
Sep 24 '08 #1
5 5379
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
Sep 28 '08 #2
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
Sep 29 '08 #3
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
Sep 29 '08 #4
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
Sep 29 '08 #5
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
Sep 30 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Abhishek Srivastava | last post by:
Hello All, How do I completly and totally disable any kind of caching when making a HttpWebRequest. I have an application which downloads a file from the web. This file is updated on a daily...
3
by: Søren Reinke | last post by:
Hi there For at project i need to build a Soap proxy with build in caching functionality. The reason is our backend system that we communicate with by Soap, does not always answer (break...
7
by: Nalaka | last post by:
Hi, I created a sinple web service that returns a dataSet. Then I created a client program that uses this web service (that returns the Dataset). My question is, how did the client figure...
8
by: A.M-SG | last post by:
Hi, I understand that we can install SOAP extensions through web.config at the server side. How do I install them at the client proxy side? Thank you, Alan
0
by: John | last post by:
We want to prevent the caching in our project, so we have the following line of code in the page load function Response.AppendHeader("Cache-Control", "no-store"); But when we are using proxy...
1
by: khubieb | last post by:
Situation: We have to connect to a 3rd party XML Web Service outside our LAN by adding a WCF Service Reference to a simple console application Problem: When attempting to invoke any of the...
3
by: =?Utf-8?B?RGFuaWVs?= | last post by:
Hi, I have a winform client which consumes a WCF service. I have a single service client(proxy) at the winform side, but spread the service calls into multiple threads so that they can do works...
2
by: Doken13 | last post by:
I got an intranet web site and there is a proxy on the network. I want to retreive a client's IP, how could I get it ?
5
by: =?Utf-8?B?TWFyaw==?= | last post by:
Hi... I've got a .Net client to a soap service that works for the most part, but there are a couple of things I'd like to improve: 1) the first request to the client wrapper always takes...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.