At the moment, I have a service that looks like this:
[ServiceContract]
public interface ICalculatorService
{
    [OperationContract]
    int Add(int a, int b);
    [OperationContract]
    int Subtract(int a, int b);
}
[ServiceBehavior(...)]
public class CalculatorService : ICalculatorService
{
    private readonly IAdder _adder;
    private readonly ISubtractor _subtractor;
    public CalculatorService(IAdder adder, ISubtractor subtractor)
    {
         _adder = adder;
         _subtractor = subtractor;
    }
    public int Add(int a, int b) { return _adder.Add(a, b); }
    public int Subtract(int a, int b) { return _subtractor.Subtract(a, b); }
}
public class CalculatorInstaller : IWindsorInstaller
{
     //magic
     container.Register(Component.For<IAdder>().ImplementedBy<Adder>());
     
container.Register(Component.For<ISubtractor>().ImplementedBy<Subtractor>());
     
container.Register(Component.For<ICalculatorService>().ImplementedBy<CalculatorService>());
     //more magic
}
(i think you know what the implementations should look like)

Now, for what its worth, the CalculatorService is just a big composite that 
does nothing else than forwarding calls to the internal components.
So...what do we need all that boilerplate code for when Castle supports 
proxies, mixins, forwards and all those fancy features?

The idea would be to get rid of CalculatorService, as all of its methods 
are implemented somewhere else and could be used right away. In practise, I 
probably wouldn't use the internal implementation right away but introduce 
some thin layer instead (for contract <-> model conversion and the actual 
forward to the internal implementation).

Then I tried to split things up, register everything in the container, and 
start the ServiceHost...just to get an ArgumentException from 
System.ServiceModel, because "ServiceHost only supports class service 
types". 
Maybe I'm wrong using the DefaultServiceHostFactory from the WCF Facility, 
or maybe I just forgot something in the registration.

Anyways, right now it looks like this:
[ServiceContract]
public interface ICalculatorService //: IAdder, ISubtractor
{
}
//no class CalculatorService...but then: where to put my ServiceBehavior?
public interface IAdder
{
    [OperationContract]
    int Add(int a, int b);
}
public class CalculatorInstaller : IWindsorInstaller
{
     //magic
     container.Register(Component.For<IAdder>().ImplementedBy<Adder>());
     
container.Register(Component.For<ISubtractor>().ImplementedBy<Subtractor>());
     container.Register(Component.For<ICalculatorService>()
         .Proxy.MixIns(m => m.Component<IAdder>().Component<ISubtractor>());
     //more magic
}
Too good to be true, doesn't really work that way. Playing around with the 
components (For<Interface>/ImplementedBy<Concrete> vs. 
For<Concrete>/Forward<Interface>) and the service itself (providing a dummy 
class that has no operations, deriving the service interface from the 
smaller ones, Interface vs. Concrete in the mixins Component call, etc) 
gave me all sorts of runtime errors (from System.ServiceModel "does not 
provide any operations" to Windsor "cannot resolve (I)Adder" and "cannot 
find a public constructor for ICalculatorService).

I feel like I'm really close, but I don't know what I'm missing (perhaps a 
special ProxyActivator or Interceptor that should be registered with 
ICalculatorService?)
Any help on this would be greatly appreciated.

And, for the sake of completeness, the current service implementation 
splits up its concerns into different files, using partial classes. This 
works on a source code level, but not really to separate concerns of the 
class itself. A service class like that probably is never really pretty, 
but it would be a start to hide the gory details within smaller classes 
that are simply mixed in (think one big service class with 20 operations 
and 15 ctor-injected dependencies vs. 5 small service classes with 4 
operations each and considerably less ctor parameters).

- BhaaL

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Users" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/castle-project-users/-/be-MH2U-3cAJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-users?hl=en.

Reply via email to