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.