WCF Client Proxy and caching...

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?TWFyaw==?=

    #1

    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.ServiceM odel 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<TCha nnel>
    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
  • Tiago Halm

    #2
    Re: WCF Client Proxy and caching...

    Mark,

    When using ChannelBase, you're in fact calling:
    - ChannelFactory. Create
    - factory.CreateC hannel
    - ... 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:


    hope it helps
    Tiago Halm

    "Mark" <Mark@discussio ns.microsoft.co mwrote in message
    news:9ABBDF3A-211A-4361-8C70-2E66DB660602@mi crosoft.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.ServiceM odel 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<TCha nnel>
    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

    Comment

    • =?Utf-8?B?TWFyaw==?=

      #3
      Re: WCF Client Proxy and caching...

      Thanks for the reply.

      Just to clarify, I should cache the factory created by CreateFactory(O f 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 WcfWebServicePr oxy(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.ICommunicat ionObject = TryCast(mProxy,
      WCF.ICommunicat ionObject)

      Try
      If channel IsNot Nothing Then
      If channel.State <WCF.Communicat ionState.Faulte d Then
      channel.Close()
      Else
      channel.Abort()
      End If
      End If

      Catch ex As WCF.Communicati onException
      channel.Abort()
      ExceptionPublis her.CallPublish ExceptionWebSer vice(ex)
      Catch ex As TimeoutExceptio n
      channel.Abort()
      ExceptionPublis her.CallPublish ExceptionWebSer vice(ex)
      Catch ex As Exception
      channel.Abort()
      ExceptionPublis her.CallPublish ExceptionWebSer vice(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.Dis pose
      ' Do not change this code. Put cleanup code in Dispose(ByVal
      disposing As Boolean) above.
      Dispose(True)
      GC.SuppressFina lize(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.CreateC hannel
      - ... 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:

      >
      hope it helps
      Tiago Halm
      >
      "Mark" <Mark@discussio ns.microsoft.co mwrote in message
      news:9ABBDF3A-211A-4361-8C70-2E66DB660602@mi crosoft.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.ServiceM odel 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<TCha nnel>
      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
      >

      Comment

      • Tiago Halm

        #4
        Re: WCF Client Proxy and caching...

        The class you're writing below looks similar to the class here:


        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" <Mark@discussio ns.microsoft.co mwrote in message
        news:CA394BEB-296F-46C6-A0A9-12ECDB8A4A22@mi crosoft.com...
        Thanks for the reply.
        >
        Just to clarify, I should cache the factory created by CreateFactory(O f
        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 WcfWebServicePr oxy(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.ICommunicat ionObject = TryCast(mProxy,
        WCF.ICommunicat ionObject)
        >
        Try
        If channel IsNot Nothing Then
        If channel.State <WCF.Communicat ionState.Faulte d Then
        channel.Close()
        Else
        channel.Abort()
        End If
        End If
        >
        Catch ex As WCF.Communicati onException
        channel.Abort()
        ExceptionPublis her.CallPublish ExceptionWebSer vice(ex)
        Catch ex As TimeoutExceptio n
        channel.Abort()
        ExceptionPublis her.CallPublish ExceptionWebSer vice(ex)
        Catch ex As Exception
        channel.Abort()
        ExceptionPublis her.CallPublish ExceptionWebSer vice(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.Dis pose
        ' Do not change this code. Put cleanup code in Dispose(ByVal
        disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFina lize(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.CreateC hannel
        >- ... use channel ...
        >- channel.Close
        >- factory.Close
        >>
        >ChannelFacto ry 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
        >authenticati on
        >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" <Mark@discussio ns.microsoft.co mwrote in message
        >news:9ABBDF3 A-211A-4361-8C70-2E66DB660602@mi crosoft.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.ServiceM odel 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<TCha nnel>
        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
        >>

        Comment

        • =?Utf-8?B?TWFyaw==?=

          #5
          Re: WCF Client Proxy and caching...

          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:

          >
          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" <Mark@discussio ns.microsoft.co mwrote in message
          news:CA394BEB-296F-46C6-A0A9-12ECDB8A4A22@mi crosoft.com...
          Thanks for the reply.

          Just to clarify, I should cache the factory created by CreateFactory(O f
          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 WcfWebServicePr oxy(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.ICommunicat ionObject = TryCast(mProxy,
          WCF.ICommunicat ionObject)

          Try
          If channel IsNot Nothing Then
          If channel.State <WCF.Communicat ionState.Faulte d Then
          channel.Close()
          Else
          channel.Abort()
          End If
          End If

          Catch ex As WCF.Communicati onException
          channel.Abort()
          ExceptionPublis her.CallPublish ExceptionWebSer vice(ex)
          Catch ex As TimeoutExceptio n
          channel.Abort()
          ExceptionPublis her.CallPublish ExceptionWebSer vice(ex)
          Catch ex As Exception
          channel.Abort()
          ExceptionPublis her.CallPublish ExceptionWebSer vice(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.Dis pose
          ' Do not change this code. Put cleanup code in Dispose(ByVal
          disposing As Boolean) above.
          Dispose(True)
          GC.SuppressFina lize(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.CreateC hannel
          - ... 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:

          >
          hope it helps
          Tiago Halm
          >
          "Mark" <Mark@discussio ns.microsoft.co mwrote in message
          news:9ABBDF3A-211A-4361-8C70-2E66DB660602@mi crosoft.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.ServiceM odel 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<TCha nnel>
          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
          >
          >

          Comment

          • Tiago Halm

            #6
            Re: WCF Client Proxy and caching...

            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.cl ose" 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.


            Tiago Halm

            "Mark" <Mark@discussio ns.microsoft.co mwrote in message
            news:72277C5B-AD2A-428F-B50D-1360B45080B2@mi crosoft.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
            >implementati on 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" <Mark@discussio ns.microsoft.co mwrote in message
            >news:CA394BE B-296F-46C6-A0A9-12ECDB8A4A22@mi crosoft.com...
            Thanks for the reply.
            >
            Just to clarify, I should cache the factory created by CreateFactory(O f
            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 WcfWebServicePr oxy(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.ICommunicat ionObject = TryCast(mProxy,
            WCF.ICommunicat ionObject)
            >
            Try
            If channel IsNot Nothing Then
            If channel.State <WCF.Communicat ionState.Faulte d
            Then
            channel.Close()
            Else
            channel.Abort()
            End If
            End If
            >
            Catch ex As WCF.Communicati onException
            channel.Abort()
            ExceptionPublis her.CallPublish ExceptionWebSer vice(ex)
            Catch ex As TimeoutExceptio n
            channel.Abort()
            ExceptionPublis her.CallPublish ExceptionWebSer vice(ex)
            Catch ex As Exception
            channel.Abort()
            ExceptionPublis her.CallPublish ExceptionWebSer vice(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.Dis pose
            ' Do not change this code. Put cleanup code in
            Dispose(ByVal
            disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFina lize(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.CreateC hannel
            >- ... use channel ...
            >- channel.Close
            >- factory.Close
            >>
            >ChannelFacto ry 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
            >authenticati on
            >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" <Mark@discussio ns.microsoft.co mwrote in message
            >news:9ABBDF3 A-211A-4361-8C70-2E66DB660602@mi crosoft.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.ServiceM odel 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<TCha nnel>
            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
            >>
            >>

            Comment

            Working...