WCF Facility, composed service with MixIns?

19 views
Skip to first unread message

bhaa...@gmail.com

unread,
Jan 17, 2013, 8:22:40 AM1/17/13
to castle-pro...@googlegroups.com
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
Reply all
Reply to author
Forward
0 new messages