WCF Integration Facility Updates

604 views
Skip to first unread message

Craig Neuwirt

unread,
Mar 24, 2008, 11:29:13 AM3/24/08
to castle-pro...@googlegroups.com
I have just committed some updates to the WCF Integration Facility to add consistent and transparent support for both clients and services.

Here is a summary of the features

  • Client Side
    • Automatic generation of WCF client channels when a component has been configured for WCF Client capabilities.
        new WindsorContainer().Register( Component.For<IOperations>()
                    .CustomDependencies(new
                     {
                            clientModel = new WcfClientModel()
                            {
                                Endpoint = WcfEndpoint
                                    .BoundTo(new NetTcpBinding())
                                    .At("net.tcp://localhost/Operations")
                            }
                     })
                );

            IOperations client = windsorContainer.Resolve<IOperations>();

    • Any Endpoint, or Operation behaviors registered in the kernel will be attached to the channels.
        new WindsorContainer().Register(
                 Component.For<IOperationBehavior>().ImplementedBy<NetDataContractFormatBehavior>()
                 );

    • Automatic cleanup of channel proxy when component is released (channel.Close() vs channel.Abort)
      • No need to cast proxy to IChannel and call Dispose
    • Automatic detection of unhanded channel faults and re-acquisition of new channel proxy
      • You can continue to use client proxy even after an exception occurs.  By default WCF makes all faulted channels unavailable
    • Ability to use the client channel configuration from App.Config/Web.Config (if you really must!!)
        new WindsorContainer().Register( Component.For<IAmUsingWindsor>()
                .CustomDependencies(new
                {
                    clientModel = new WcfClientModel()
                    {
                        Endpoint = WcfEndpoint
                            .FromConfiguration("WSHttpBinding_IAmUsingWindsor")
                    }
                }));

    • Custom Registration Provider to simplify batch registration of channels
       new WindsorContainer()
                .AddFacility<WcfFacility>()
                .Register(WcfClient.ForChannels(
                    new WcfClientModel()
                    {
                        Endpoint = WcfEndpoint.ForContract<IOperations>()
                            .BoundTo(new NetTcpBinding())
                            .At("net.tcp://localhost/Operations")
                    },
                    new WcfClientModel()
                    {
                        Endpoint = WcfEndpoint.ForContract<IAmUsingWindsor>()
                            .BoundTo(new BasicHttpBinding())
                            .At("http://localhost:27198/UsingWindsor.svc")
                    }))

    • Support for Xml Configuration (if you still use it)
        <component id="usingWindsor"
                   type="Castle.Facilities.WcfIntegration.Demo.IAmUsingWindsor,
                         Castle.Facilities.WcfIntegration.Demo"
                   wcfEndpointConfiguration="WSHttpBinding_IAmUsingWindsor">
        </component>

    • Client extensibility  interface IClientChannelBuilder
      • Supports plugging in other ways to create channels (e.g. RESTful services)
  • Service Side
    • Automatic management of ServiceHost when a component is configured for WCF Service capabilities
          new WindsorContainer()
                .AddFacility<WcfFacility>()
                .Register( Component.For<IOperations>().ImplementedBy<Operations>()
                    .CustomDependencies(new
                    {
                        number = 42,
                        serviceModel = new WcfServiceModel()
                            .AddEndpoints(
                                WcfEndpoint.BoundTo(new NetTcpBinding())
                                    .At("net.tcp://localhost/Operations")
                                    )
                    })
                )
    • Any Service, Endpoint, or Operation behaviors registered in the kernel will be attached to the channels.
         new WindsorContainer()
                .Register(
                    Component.For<LoggingInterceptor>(),
                    Component.For<IServiceBehavior>().ImplementedBy<CallCountServiceBehavior>(),
                    Component.For<IEndpointBehavior>().ImplementedBy<UnitOfworkEndPointBehavior>(),
                    Component.For<IOperationBehavior>().ImplementedBy<NetDataContractFormatBehavior>()
                    );

    • Ability to use the service channel configuration from App.Config/Web.Config (if you really must!!)
        new WindsorContainer()
                .AddFacility<WcfFacility>()
                .Register(Component.For<UsingWindsor>()
                    .CustomDependencies(new
                    {
                        number = 42,
                        serviceModel = new WcfServiceModel()
                    })
                )

    • Support for Xml Configuration (if you still use it)
         <component id="usingwindsor_svc"
                   service="Castle.Facilities.WcfIntegration.Demo.IAmUsingWindsor,
                            Castle.Facilities.WcfIntegration.Demo"
                   type="Castle.Facilities.WcfIntegration.Demo.UsingWindsor,
                         Castle.Facilities.WcfIntegration.Demo"
                   wcfServiceHost="true">
            <parameters>
                <number>42</number>
            </parameters>
        </component>

    • Supports endpoints with relative addressing
        new WindsorContainer()
                .AddFacility<WcfFacility>()
                .Register( Component.For<Operations>()
                    .CustomDependencies(new
                    {
                        number = 42,
                        serviceModel = new WcfServiceModel()
                            .AddBaseAddresses(
                                "net.tcp://localhost/Operations",
                                "http://localhost:27198/UsingWindsor.svc")
                            .AddEndpoints(
                                WcfEndpoint.ForContract<IOperations>()
                                    .BoundTo(new NetTcpBinding()),
                                WcfEndpoint.ForContract<IOperationsEx>()
                                    .BoundTo(new BasicHttpBinding())
                                    .At("Extended")
                                )
                    })
                );
    • Automatic initialization of the WindsorServiceHostFactory for web apps
      • No need to call WindsorServiceHostFactory(kernel) in Global asax anymore.
    • Service extensibility interface IServiceHostBuilder
      • Support plugging in other ways to create ServiceHosts.

Craig

Ayende Rahien

unread,
Mar 24, 2008, 11:42:58 AM3/24/08
to castle-pro...@googlegroups.com
Craig,
You just won the first hostile blogging award.
This is just too good to leave on the mailing list.

Craig Neuwirt

unread,
Mar 24, 2008, 12:54:02 PM3/24/08
to castle-pro...@googlegroups.com
I'm honored  :-)

Ruprict

unread,
Mar 29, 2008, 4:24:10 PM3/29/08
to Castle Project Development List
Craig,

So, do you still need to register the services in web.config? If not,
can you give a Binsor-ish example of registering a service, complete
with serviceBehaviors, endpointBehaviors, multiple endpoints, etc.

(I am sorry if this is readily obvious from what you have already
written.)

Thanks,
Glenn


On Mar 24, 12:54 pm, "Craig Neuwirt" <cneuw...@gmail.com> wrote:
> I'm honored :-)
>
> On Mon, Mar 24, 2008 at 10:42 AM, Ayende Rahien <aye...@ayende.com> wrote:
> > Craig,
> > You just won the first hostile blogging award.
> > This is just too good to leave on the mailing list.
>
> > On Mon, Mar 24, 2008 at 5:29 PM, Craig Neuwirt <cneuw...@gmail.com> wrote:
>
> > > I have just committed some updates to the WCF Integration Facility to
> > > add consistent and transparent support for both clients and services.
>
> > > Here is a summary of the features
>
> > > - *Client Side
> > > *
> > > - *Automatic generation of WCF client channels when a
> > > component has been configured for WCF Client capabilities.*
>
> > > new WindsorContainer().Register( Component.For<IOperations>()
> > > .CustomDependencies(new
> > > {
> > > clientModel = new WcfClientModel()
> > > {
> > > Endpoint = WcfEndpoint
> > > .BoundTo(new NetTcpBinding())
> > > .At("net
> > > .tcp://localhost/Operations")
> > > }
> > > })
> > > );
>
> > > IOperations client = windsorContainer.Resolve
> > > <IOperations>();
>
> > > - *Any Endpoint, or Operation behaviors registered in the kernel
> > > will be attached to the channels.*
>
> > > new WindsorContainer().Register(
> > > Component.For
> > > <IOperationBehavior>().ImplementedBy<NetDataContractFormatBehavior>()
> > > );
>
> > > - *Automatic cleanup of channel proxy when component is released (
> > > channel.Close() vs channel.Abort)*
> > > - No need to cast proxy to IChannel and call Dispose
>
> > > - *Automatic detection of unhanded channel faults and
> > > re-acquisition of new channel proxy*
> > > - You can continue to use client proxy even after an
> > > exception occurs. By default WCF makes all faulted channels unavailable
>
> > > - *Ability to use the client channel configuration from App.Config/Web.Config
> > > (if you really must!!)*
>
> > > new WindsorContainer().Register( Component.For
> > > <IAmUsingWindsor>()
> > > .CustomDependencies(new
> > > {
> > > clientModel = new WcfClientModel()
> > > {
> > > Endpoint = WcfEndpoint
>
> > > .FromConfiguration("WSHttpBinding_IAmUsingWindsor")
> > > }
> > > }));
>
> > > - *Custom Registration Provider to simplify batch registration of
> > > channels*
>
> > > new WindsorContainer()
> > > .AddFacility<WcfFacility>()
> > > .Register(WcfClient.ForChannels(
> > > new WcfClientModel()
> > > {
> > > Endpoint = WcfEndpoint.ForContract
> > > <IOperations>()
> > > .BoundTo(new NetTcpBinding())
> > > .At("net.tcp://localhost/Operations")
> > > },
> > > new WcfClientModel()
> > > {
> > > Endpoint = WcfEndpoint.ForContract
> > > <IAmUsingWindsor>()
> > > .BoundTo(new BasicHttpBinding())
> > > .At("http://localhost:27198/UsingWindsor.svc
> > > ")
> > > }))
>
> > > - *Support for Xml Configuration (if you still use it)*
>
> > > <component id="usingWindsor"
> > > type="
> > > Castle.Facilities.WcfIntegration.Demo.IAmUsingWindsor,
> > > Castle.Facilities.WcfIntegration.Demo"
> > > *
> > > wcfEndpointConfiguration="WSHttpBinding_IAmUsingWindsor"*>
> > > </component>
>
> > > - *Client extensibility interface IClientChannelBuilder*
> > > - Supports plugging in other ways to create channels (
> > > e.g. RESTful services)
>
> > > - Service Side
> > > - *Automatic management of ServiceHost when a component is
> > > configured for WCF Service capabilities*
>
> > > new WindsorContainer()
> > > .AddFacility<WcfFacility>()
> > > .Register( Component.For
> > > <IOperations>().ImplementedBy<Operations>()
> > > .CustomDependencies(new
> > > {
> > > number = 42,
> > > serviceModel = new WcfServiceModel()
> > > .AddEndpoints(
> > > WcfEndpoint.BoundTo(new NetTcpBinding())
> > > .At("net
> > > .tcp://localhost/Operations")
> > > )
> > > })
> > > )
>
> > > - *Any Service, Endpoint, or Operation behaviors registered in the
> > > kernel will be attached to the channels.*
>
> > > new WindsorContainer()
> > > .Register(
> > > Component.For<LoggingInterceptor>(),
> > > Component.For
> > > <IServiceBehavior>().ImplementedBy<CallCountServiceBehavior>(),
> > > Component.For
> > > <IEndpointBehavior>().ImplementedBy<UnitOfworkEndPointBehavior>(),
> > > Component.For
> > > <IOperationBehavior>().ImplementedBy<NetDataContractFormatBehavior>()
> > > );
>
> > > - *Ability to use the service channel configuration from
> > > App.Config/Web.Config (if you really must!!)*
>
> > > new WindsorContainer()
> > > .AddFacility<WcfFacility>()
> > > .Register(Component.For<UsingWindsor>()
> > > .CustomDependencies(new
> > > {
> > > number = 42,
> > > serviceModel = new WcfServiceModel()
> > > })
> > > )
>
> > > - *Support for Xml Configuration (if you still use it)*
>
> > > <component id="usingwindsor_svc"
> > > service="
> > > Castle.Facilities.WcfIntegration.Demo.IAmUsingWindsor,
> > > Castle.Facilities.WcfIntegration.Demo"
> > > type="
> > > Castle.Facilities.WcfIntegration.Demo.UsingWindsor,
> > > Castle.Facilities.WcfIntegration.Demo"
> > > *wcfServiceHost="true"*>
> > > <parameters>
> > > <number>42</number>
> > > </parameters>
> > > </component>
>
> > > - *Supports endpoints with relative addressing*
>
> > > new WindsorContainer()
> > > .AddFacility<WcfFacility>()
> > > .Register( Component.For<Operations>()
> > > .CustomDependencies(new
> > > {
> > > number = 42,
> > > serviceModel = new WcfServiceModel()
> > > .AddBaseAddresses(
> > > "net.tcp://localhost/Operations",
> > > "http://localhost:27198/UsingWindsor.svc
> > > ")
> > > .AddEndpoints(
> > > WcfEndpoint.ForContract<IOperations>()
> > > .BoundTo(new NetTcpBinding()),
> > > WcfEndpoint.ForContract<IOperationsEx>()
> > > .BoundTo(new BasicHttpBinding())
> > > .At("Extended")
> > > )
> > > })
> > > );
>
> > > - *Automatic initialization of the WindsorServiceHostFactory for
> > > web apps*
> > > - No need to call WindsorServiceHostFactory(kernel) in
> > > Global asax anymore.
>
> > > - *Service extensibility interface IServiceHostBuilder*
> > > - Support plugging in other ways to create
> > > ServiceHosts.
>
> > > Craig

Craig Neuwirt

unread,
Mar 29, 2008, 4:31:10 PM3/29/08
to castle-pro...@googlegroups.com
Nothing in Web.config

This is for an IIS hosted, I'll make one for binsor non-iis shortly

import System.Reflection
import System.ServiceModel
import System.ServiceModel.Description from System.ServiceModel
import Castle.Facilities.Logging
import Castle.Facilities.WcfIntegration
import Rhino.Commons from Rhino.Commons.NHibernate

facility WcfFacility

component 'reservation_svc', IReservationService, ReservationService:
    ServiceModel = WcfServiceModel().Hosted() \
        .AddEndpoints(WcfEndpoint.BoundTo(BasicHttpBinding()))
   
component IServiceBehavior, LoggingServiceBehavior
component IEndpointBehavior, UnitOfWorkEndpointBehavior

Ruprict

unread,
Mar 31, 2008, 2:22:37 PM3/31/08
to Castle Project Development List
Yay!!!

I am gonna try and throw a blog together about this, which I will send
your way for critique early this week.

Really great stuff, man. Oh, and I found your blog too....already
subscribed.


On Mar 29, 4:31 pm, "Craig Neuwirt" <cneuw...@gmail.com> wrote:
> Nothing in Web.config
>
> This is for an IIS hosted, I'll make one for binsor non-iis shortly
>
> import System.Reflection
> import System.ServiceModel
> import System.ServiceModel.Description from System.ServiceModel
> import Castle.Facilities.Logging
> import Castle.Facilities.WcfIntegration
> import Rhino.Commons from Rhino.Commons.NHibernate
>
> facility WcfFacility
>
> component 'reservation_svc', IReservationService, ReservationService:
> ServiceModel = WcfServiceModel().Hosted() \
> .AddEndpoints(WcfEndpoint.BoundTo(BasicHttpBinding()))
>
> component IServiceBehavior, LoggingServiceBehavior
> component IEndpointBehavior, UnitOfWorkEndpointBehavior
>

Craig Neuwirt

unread,
Mar 31, 2008, 4:33:52 PM3/31/08
to castle-pro...@googlegroups.com
sounds good.

Doug Mayer

unread,
Apr 2, 2008, 2:07:03 AM4/2/08
to Castle Project Development List
This stuff is great--I have everything working on my service side.
Does anyone have an example of setting up the WcfFacility to
automatically create the proxy class (as shown in the first example)
in Binsor? I'm having some trouble implementing the component. This
is what I'm trying to convert to Binsor:

new
WindsorContainer().Register( Component.For<IOperations>()
.CustomDependencies(new
{
clientModel = new WcfClientModel()
{
Endpoint = WcfEndpoint
.BoundTo(new NetTcpBinding())
.At("net.tcp://localhost/
Operations")
}
})
);
IOperations client =
windsorContainer.Resolve<IOperations>();

On Mar 29, 3:31 pm, "Craig Neuwirt" <cneuw...@gmail.com> wrote:
> Nothing in Web.config
>
> This is for an IIS hosted, I'll make one for binsor non-iis shortly
>
> import System.Reflection
> import System.ServiceModel
> import System.ServiceModel.Description from System.ServiceModel
> import Castle.Facilities.Logging
> import Castle.Facilities.WcfIntegration
> import Rhino.Commons from Rhino.Commons.NHibernate
>
> facility WcfFacility
>
> component 'reservation_svc', IReservationService, ReservationService:
>     ServiceModel = WcfServiceModel().Hosted() \
>         .AddEndpoints(WcfEndpoint.BoundTo(BasicHttpBinding()))
>
> component IServiceBehavior, LoggingServiceBehavior
> component IEndpointBehavior, UnitOfWorkEndpointBehavior
>

Craig Neuwirt

unread,
Apr 2, 2008, 5:47:42 AM4/2/08
to castle-pro...@googlegroups.com
try

component IOperations:
   ClientModel = WcfClientModel( WcfEndpoint.BoundTo(NetTcpBinding()).At("net.tcp://localhost/Operations") )

      
component 'reservation_svc', IReservationService, ReservationService:
>     ServiceModel = WcfServiceModel().Hosted() \
>         .AddEndpoints(WcfEndpoint
.BoundTo(BasicHttpBinding()))


Ruprict

unread,
Apr 2, 2008, 8:46:56 AM4/2/08
to Castle Project Development List
FWIW, I posted on the server-side (I saw you got it working) at
http://ruprict.wordpress.com and am eager for feedback/critique.
Craig mentioned he might do a post on the client side stuff later....
> ...
>
> read more »

João Bragança

unread,
Apr 2, 2008, 11:40:49 AM4/2/08
to Castle Project Development List
"Any Endpoint, or Operation behaviors registered in the kernel will
be attached to the channels"

What if we defined several endpoint behaviors, but only wanted to
apply them to certain wcf components? For example, I would want the
endpoint behavior UserAccountRouterBehavior applied to services I
wrote, but I wouldn't want them applied to the eBay client channel.

On Mar 24, 8:29 am, "Craig Neuwirt" <cneuw...@gmail.com> wrote:
> I have just committed some updates to the WCF Integration Facility to add
> consistent and transparent support for both clients and services.
>
> Here is a summary of the features
>
>    - *Client Side
>    *
>       - *Automatic generation of WCF client channels when a component
>       has been configured for WCF Client capabilities.*
>
>         new WindsorContainer().Register( Component.For<IOperations>()
>                     .CustomDependencies(new
>                      {
>                             clientModel = new WcfClientModel()
>                             {
>                                 Endpoint = WcfEndpoint
>                                     .BoundTo(new NetTcpBinding())
>                                     .At("net.tcp://localhost/Operations")
>                             }
>                      })
>                 );
>
>             IOperations client = windsorContainer.Resolve<IOperations>();
>
>    - *Any Endpoint, or Operation behaviors registered in the kernel will
>       be attached to the channels.*
>
>         new WindsorContainer().Register(
>                  Component.For
> <IOperationBehavior>().ImplementedBy<NetDataContractFormatBehavior>()
>                  );
>
>    - *Automatic cleanup of channel proxy when component is released (
>       channel.Close() vs channel.Abort)*
>          - No need to cast proxy to IChannel and call Dispose
>
>    - *Automatic detection of unhanded channel faults and re-acquisition
>       of new channel proxy*
>          - You can continue to use client proxy even after an
>          exception occurs.  By default WCF makes all faulted channels
> unavailable
>
>    - *Ability to use the client channel configuration from
> App.Config/Web.Config
>       (if you really must!!)*
>
>         new WindsorContainer().Register( Component.For<IAmUsingWindsor>()
>                 .CustomDependencies(new
>                 {
>                     clientModel = new WcfClientModel()
>                     {
>                         Endpoint = WcfEndpoint
>
> .FromConfiguration("WSHttpBinding_IAmUsingWindsor")
>                     }
>                 }));
>
>    - *Custom Registration Provider to simplify batch registration of
>       channels*
>
>        new WindsorContainer()
>                 .AddFacility<WcfFacility>()
>                 .Register(WcfClient.ForChannels(
>                     new WcfClientModel()
>                     {
>                         Endpoint = WcfEndpoint.ForContract<IOperations>()
>                             .BoundTo(new NetTcpBinding())
>                             .At("net.tcp://localhost/Operations")
>                     },
>                     new WcfClientModel()
>                     {
>                         Endpoint = WcfEndpoint.ForContract
> <IAmUsingWindsor>()
>                             .BoundTo(new BasicHttpBinding())
>                             .At("http://localhost:27198/UsingWindsor.svc")
>                     }))
>
>    - *Support for Xml Configuration (if you still use it)*
>
>         <component id="usingWindsor"
>                    type="
> Castle.Facilities.WcfIntegration.Demo.IAmUsingWindsor,
>                          Castle.Facilities.WcfIntegration.Demo"
>                    *wcfEndpointConfiguration="WSHttpBinding_IAmUsingWindsor"
> *>
>         </component>
>
>    - *Client extensibility  interface IClientChannelBuilder*
>          - Supports plugging in other ways to create channels (e.g.
>          RESTful services)
>
>    - Service Side
>       - *Automatic management of ServiceHost when a component is
>       configured for WCF Service capabilities*
>
>           new WindsorContainer()
>                 .AddFacility<WcfFacility>()
>                 .Register( Component.For
> <IOperations>().ImplementedBy<Operations>()
>                     .CustomDependencies(new
>                     {
>                         number = 42,
>                         serviceModel = new WcfServiceModel()
>                             .AddEndpoints(
>                                 WcfEndpoint.BoundTo(new NetTcpBinding())
>                                     .At("net.tcp://localhost/Operations")
>                                     )
>                     })
>                 )
>
>    - *Any Service, Endpoint, or Operation behaviors registered in the
>       kernel will be attached to the channels.*
>
>          new WindsorContainer()
>                 .Register(
>                     Component.For<LoggingInterceptor>(),
>                     Component.For
> <IServiceBehavior>().ImplementedBy<CallCountServiceBehavior>(),
>                     Component.For
> <IEndpointBehavior>().ImplementedBy<UnitOfworkEndPointBehavior>(),
>                     Component.For
> <IOperationBehavior>().ImplementedBy<NetDataContractFormatBehavior>()
>                     );
>
>    - *Ability to use the service channel configuration from
> App.Config/Web.Config
>       (if you really must!!)*
>
>         new WindsorContainer()
>                 .AddFacility<WcfFacility>()
>                 .Register(Component.For<UsingWindsor>()
>                     .CustomDependencies(new
>                     {
>                         number = 42,
>                         serviceModel = new WcfServiceModel()
>                     })
>                 )
>
>    - *Support for Xml Configuration (if you still use it)*
>
>          <component id="usingwindsor_svc"
>                    service="
> Castle.Facilities.WcfIntegration.Demo.IAmUsingWindsor,
>                             Castle.Facilities.WcfIntegration.Demo"
>                    type="Castle.Facilities.WcfIntegration.Demo.UsingWindsor,
>
>                          Castle.Facilities.WcfIntegration.Demo"
>                    *wcfServiceHost="true"*>
>             <parameters>
>                 <number>42</number>
>             </parameters>
>         </component>
>
>    - *Supports endpoints with relative addressing*
>
>         new WindsorContainer()
>                 .AddFacility<WcfFacility>()
>                 .Register( Component.For<Operations>()
>                     .CustomDependencies(new
>                     {
>                         number = 42,
>                         serviceModel = new WcfServiceModel()
>                             .AddBaseAddresses(
>                                 "net.tcp://localhost/Operations",
>                                 "http://localhost:27198/UsingWindsor.svc")
>                             .AddEndpoints(
>                                 WcfEndpoint.ForContract<IOperations>()
>                                     .BoundTo(new NetTcpBinding()),
>                                 WcfEndpoint.ForContract<IOperationsEx>()
>                                     .BoundTo(new BasicHttpBinding())
>                                     .At("Extended")
>                                 )
>                     })
>                 );
>
>    - *Automatic initialization of the WindsorServiceHostFactory for web
>       apps*
>          - No need to call WindsorServiceHostFactory(kernel) in
>          Global asax anymore.
>
>    - *Service extensibility interface IServiceHostBuilder*
>          - Support plugging in other ways to create ServiceHosts.
>
> Craig

Craig Neuwirt

unread,
Apr 2, 2008, 11:47:02 AM4/2/08
to castle-pro...@googlegroups.com
This is something I am trying to support right now.  I have some ideas on how I am going to do it, but any feedback you have as to how you would like to use that is welcome.

I think the only way to support it right now would be to construct a ServiceEndpoint and assign the behaviors directly.

craig

Ayende Rahien

unread,
Apr 2, 2008, 12:54:52 PM4/2/08
to castle-pro...@googlegroups.com
What about doing something like:

component IMyService:
     Behaviors: [ Behavior1(), Behavior2()] # <-- applies only to this one.

Craig Neuwirt

unread,
Apr 2, 2008, 1:52:51 PM4/2/08
to castle-pro...@googlegroups.com
Since I don't have a WCF DSL for Binsor I was thinking of adding a Behaviors collection to the client and service models applied to the components.  These would be instances or behavior references (key or service).

I would then allow a scope attribute on the behavior component with the following options
  • all => Do the current behavior and attach to all clients and services (Default)
  • clients => attach the behaviors to all clients only
  • services => attach the behaviors to all services only
  • explicit  => Only attach when explicitly specified
What do you think?

Another feature I am supporting is the ability to have a component be associated with multiple service hosts

Doug Mayer

unread,
Apr 2, 2008, 1:57:12 PM4/2/08
to Castle Project Development List
+1 for the scoping attribute. Being able to attach to those different
groups is nice.

On Apr 2, 12:52 pm, "Craig Neuwirt" <cneuw...@gmail.com> wrote:
> Since I don't have a WCF DSL for Binsor I was thinking of adding a Behaviors
> collection to the client and service models applied to the components.
> These would be instances or behavior references (key or service).
>
> I would then allow a scope attribute on the behavior component with the
> following options
>
>    - all => Do the current behavior and attach to all clients and
>    services (Default)
>    - clients => attach the behaviors to all clients only
>    - services => attach the behaviors to all services only
>    - explicit  => Only attach when explicitly specified
>
> What do you think?
>
> Another feature I am supporting is the ability to have a component be
> associated with multiple service hosts
>
> On Wed, Apr 2, 2008 at 11:54 AM, Ayende Rahien <aye...@ayende.com> wrote:
> > What about doing something like:
>
> > component IMyService:
> >      Behaviors: [ Behavior1(), Behavior2()] # <-- applies only to this
> > one.
>
> > On Wed, Apr 2, 2008 at 6:47 PM, Craig Neuwirt <cneuw...@gmail.com> wrote:
>
> > > This is something I am trying to support right now.  I have some ideas
> > > on how I am going to do it, but any feedback you have as to how you would
> > > like to use that is welcome.
>
> > > I think the only way to support it right now would be to construct a
> > > ServiceEndpoint and assign the behaviors directly.
>
> > > craig
>
> > > On Wed, Apr 2, 2008 at 10:40 AM, João Bragança <j...@braviawebdesign.com>
> ...
>
> read more »

Ayende Rahien

unread,
Apr 2, 2008, 2:19:07 PM4/2/08
to castle-pro...@googlegroups.com
Can you give an example of how it would look like in the full script?

Craig Neuwirt

unread,
Apr 2, 2008, 2:37:30 PM4/2/08
to castle-pro...@googlegroups.com
Something like

component ServiceDebugBehavior:
    @scope = 'clients'
    IncludeExceptionDetailInFaults = true

component UnitOfWorkEndpointBehavior:
    @scope = 'explicit'

component LoggingServiceBehavior
    @scope="services"

basicHttpBinding = BasicHttpBinding()

component IReservationService, ReservationService:
    ServiceModel = WcfServiceModel()
        .AddEndpoints(WcfEndpoint.BoundTo(basicHttpBinding))

component 'flightschedules_svc', IFlightScheduleService, FlightScheduleService:
    ServiceModel = WcfServiceModel()
        .AddEndpoints(WcfEndpoint.BoundTo(basicHttpBinding))
        .AddBehaviors(UnitOfWorkEndpointBehavior)


The AddBehaviors could be types or component names or actual instances

What do you think?

João Bragança

unread,
Apr 2, 2008, 3:21:25 PM4/2/08
to Castle Project Development List
I like this approach also.

On Apr 2, 11:37 am, "Craig Neuwirt" <cneuw...@gmail.com> wrote:
> Something like...
>
> read more »
>
> component ServiceDebugBehavior:
>     @scope = 'clients'
>     IncludeExceptionDetailInFaults = true
>
> component UnitOfWorkEndpointBehavior:
>     @scope = 'explicit'
>
> component LoggingServiceBehavior
>     @scope="services"
>
> basicHttpBinding = BasicHttpBinding()
>
> component IReservationService, ReservationService:
>     ServiceModel = WcfServiceModel()
>         .AddEndpoints(WcfEndpoint.BoundTo(basicHttpBinding))
>
> component 'flightschedules_svc', IFlightScheduleService,
> FlightScheduleService:
>     ServiceModel = WcfServiceModel()
>         .AddEndpoints(WcfEndpoint.BoundTo(basicHttpBinding))
>         .AddBehaviors(UnitOfWorkEndpointBehavior)
>
> The AddBehaviors could be types or component names or actual instances
>
> What do you think?
>
>
>
> On Wed, Apr 2, 2008 at 1:19 PM, Ayende Rahien <aye...@ayende.com> wrote:
> > Can you give an example of how it would look like in the full script?
>
> > On Wed, Apr 2, 2008 at 8:52 PM, Craig Neuwirt <cneuw...@gmail.com> wrote:
>
> > > Since I don't have a WCF DSL for Binsor I was thinking of adding a
> > > Behaviors collection to the client and service models applied to the
> > > components.  These would be instances or behavior references (key or
> > > service).
>
> > > I would then allow a scope attribute on the behavior component with the
> > > following options
>
> > >    - all => Do the current behavior and attach to all clients and
> > >    services (Default)
> > >    - clients => attach the behaviors to all clients only
> > >    - services => attach the behaviors to all services only
> > >    - explicit  => Only attach when explicitly specified
>
> > > What do you think?
>
> > > Another feature I am supporting is the ability to have a component be
> > > associated with multiple service hosts
>
> > > On Wed, Apr 2, 2008 at 11:54 AM, Ayende Rahien <aye...@ayende.com>
> > > wrote:
>
> > > > What about doing something like:
>
> > > > component IMyService:
> > > >      Behaviors: [ Behavior1(), Behavior2()] # <-- applies only to this
> > > > one.
>
> > > > On Wed, Apr 2, 2008 at 6:47 PM, Craig Neuwirt <cneuw...@gmail.com>
> > > > > > >                 )- Hide quoted text -
>
> - Show quoted text -

Ayende Rahien

unread,
Apr 2, 2008, 4:04:39 PM4/2/08
to castle-pro...@googlegroups.com
+1

Ruprict

unread,
Apr 3, 2008, 6:43:10 AM4/3/08
to Castle Project Development List
Very nice.

On Apr 2, 4:04 pm, "Ayende Rahien" <aye...@ayende.com> wrote:
> +1
>
> On Wed, Apr 2, 2008 at 9:37 PM, Craig Neuwirt <cneuw...@gmail.com> wrote:
> > Something like
>
> > component ServiceDebugBehavior:
> >     @scope = 'clients'
> >     IncludeExceptionDetailInFaults = true
>
> > component UnitOfWorkEndpointBehavior:
> >     @scope = 'explicit'
>
> > component LoggingServiceBehavior
> >     @scope="services"
>
> > basicHttpBinding = BasicHttpBinding()
>
> > component IReservationService, ReservationService:
> >     ServiceModel = WcfServiceModel()
> >         .AddEndpoints(WcfEndpoint.BoundTo(basicHttpBinding))
>
> > component 'flightschedules_svc', IFlightScheduleService,
> > FlightScheduleService:
> >     ServiceModel = WcfServiceModel()
> >         .AddEndpoints(WcfEndpoint.BoundTo(basicHttpBinding))
> >         .AddBehaviors(UnitOfWorkEndpointBehavior)
>
> > The AddBehaviors could be types or component names or actual instances
>
> > What do you think?
>
> > On Wed, Apr 2, 2008 at 1:19 PM, Ayende Rahien <aye...@ayende.com> wrote:
>
> > > Can you give an example of how it would look like in the full script?
>
> > > On Wed, Apr 2, 2008 at 8:52 PM, Craig Neuwirt <cneuw...@gmail.com>
> > > wrote:
>
> > > > Since I don't have a WCF DSL for Binsor I was thinking of adding a
> > > > Behaviors collection to the client and service models applied to the
> > > > components.  These would be instances or behavior references (key or
> > > > service).
>
> > > > I would then allow a scope attribute on the behavior component with
> > > > the following options
>
> > > >    - all => Do the current behavior and attach to all clients and
> > > >    services (Default)
> > > >    - clients => attach the behaviors to all clients only
> > > >    - services => attach the behaviors to all services only
> > > >    - explicit  => Only attach when explicitly specified
>
> > > > What do you think?
>
> > > > Another feature I am supporting is the ability to have a component be
> > > > associated with multiple service hosts
>
> > > > On Wed, Apr 2, 2008 at 11:54 AM, Ayende Rahien <aye...@ayende.com>
> > > > wrote:
>
> > > > > What about doing something like:
>
> > > > > component IMyService:
> > > > >      Behaviors: [ Behavior1(), Behavior2()] # <-- applies only to
> > > > > this one.
>
> > > > > On Wed, Apr 2, 2008 at 6:47 PM, Craig Neuwirt <cneuw...@gmail.com>
> ...
>
> read more »

Craig Neuwirt

unread,
Apr 3, 2008, 3:33:36 PM4/3/08
to castle-pro...@googlegroups.com
Ok, I committed support for this.

To apply behaviors to client or services use something like


new WindsorContainer()
                .AddFacility<WcfFacility>()
                .Register(
                    Component.For<CallCountServiceBehavior>()
                        .Configuration(Attrib.ForName("scope").Eq(WcfBehaviorScope.Clients)),
                    Component.For<UnitOfworkEndPointBehavior>()
                        .Configuration(Attrib.ForName("scope").Eq(WcfBehaviorScope.Services)),

                    Component.For<IOperations>().ImplementedBy<Operations>()
                    .DependsOn(new { number = 42 })
                    .ActAs(new WcfServiceModel().AddEndpoints(

                        WcfEndpoint.BoundTo(new NetTcpBinding())
                            .At("net.tcp://localhost/Operations"))
                        )
                )

To add component specific behaviors do something like


new WindsorContainer()
                .AddFacility<WcfFacility>()
                .Register(
                    Component.For<CallCountServiceBehavior>()
                        .Configuration(Attrib.ForName("scope").Eq(WcfBehaviorScope.Explicit)),

                    Component.For<IOperations>().ImplementedBy<Operations>()
                    .DependsOn(new { number = 42 })
                    .ActAs(new WcfServiceModel()

                        .AddEndpoints(
                            WcfEndpoint.BoundTo(new NetTcpBinding())
                                .At("net.tcp://localhost/Operations"))
                        .AddBehaviors(typeof(CallCountServiceBehavior),
                                              new UnitOfworkEndPointBehavior())
                        )
                )


The WCF Facility has reached the point where it could use a post to describe its capabilities.  I will do so later today or tomorrow.

Let me know if there are additional features that would be valuable.

craig

Derek Ekins

unread,
May 16, 2008, 10:05:59 AM5/16/08
to castle-pro...@googlegroups.com
Before these changes came into play I was using the WindsorServiceHost and hosting the service from a windows service.
I could then open and close the connection when I needed to
I cant figure out what the new equivelant is. I see there is now a DefaultServiceHost but I am not sure how to use it.

Can someone offer some pointers?

2008/4/3 Craig Neuwirt <cneu...@gmail.com>:

Craig Neuwirt

unread,
May 16, 2008, 10:26:45 AM5/16/08
to castle-pro...@googlegroups.com
Derek,

 How exactly did you use WindsorServiceHost before?

Derek Ekins

unread,
May 16, 2008, 10:31:09 AM5/16/08
to castle-pro...@googlegroups.com
Something like this:

WindsorServiceHost host = new WindsorServiceHost(IoC.Container.Kernel, typeof (MyService), serviceUri);
            host.Description.Endpoints.Add(
                new ServiceEndpoint(ContractDescription.GetContract(typeof(IMyService)),
                           new WSHttpBinding(),
                           new EndpointAddress(serviceUri)));

And IMyService was registered in the container.

2008/5/16 Craig Neuwirt <cneu...@gmail.com>:

Craig Neuwirt

unread,
May 16, 2008, 10:41:36 AM5/16/08
to castle-pro...@googlegroups.com
If you register your component like this in your service, it should be up and running

   container.Register(Component.For<IMyService>()
                    .ImplementedBy<MyService>()
                    .ActAs(new DefaultServiceModel().AddEndpoints(
                        WcfEndpoint.BoundTo(new WSHttpBinding())
                            .At(serviceUri))
                        )   
                ))

Derek Ekins

unread,
May 16, 2008, 10:48:13 AM5/16/08
to castle-pro...@googlegroups.com
ok so if i did it that way then how can i stop it?
previously i had a reference to the service host so i could just stop it when i needed to.

2008/5/16 Craig Neuwirt <cneu...@gmail.com>:

Craig Neuwirt

unread,
May 16, 2008, 11:08:18 AM5/16/08
to castle-pro...@googlegroups.com
If you need that control, you can would configure the component as being hosted (the WIndows Service in this case)

   container.Register(Component
.For<IMyService>()
                    .ImplementedBy<MyService>()
                    .ActAs(new DefaultServiceModel().AddEndpoints(
                        WcfEndpoint.BoundTo(new WSHttpBinding())
                            .At(serviceUri)).Hosted()
                        )   
                ))

And create the ServiceHost explicitly

ServiceHost serviceHost = new DefaultServiceHostFactory().CreateServiceHost(typeof(IMyService).AssemblyQualifiedName, new Uri[0]);

Perhaps I can mixin an IServiceControl interface to the registered component that will allow Start() and Stop() behaviors.
Reply all
Reply to author
Forward
0 new messages