Castle Windsor è senza dubbio uno dei motori di inversione di controllo più gettonati. L’aspetto interessante è che al suo interno si trovano molte estensioni, chiamate generalmente Facility, per gestire gli scenari più comuni. Stamane mi è capitato di usare l’integrazione con WCF. In pratica si tratta di una estensione che ci permette di risolvere i servizi con un WindsorContainer.
Questa funzionalità è decisamente interessante, dato che in questo modo si risolvono tutti i problemi di dipendenza tra i vari servizi e tra i servizi e componenti esterni. Grazie ad un motore di inversione di controllo come Windsor si possono configurare i servizi in maniera estremamente flessibile. Ad esempio consideriamo il seguente servizio
[ServiceContract]
public interface IKernel
{
[OperationContract(Name = "Test")]
Int32 Test();
Implementato dalla seguente classe
public class Kernel : IKernel
{
public Int32 TestValue { get; set; }
#region IKernel Members
public Int32 Test()
{
return TestValue;
}
Come si può vedere la classe dipende dal parametro TestValue, in questo caso basta configurare il tutto con castle.
<configuration xmlns="http://www.tigraine.at/windsor-configuration.xsd">
<components>
<component id="Kernel" service="Test.Services.Interfaces.IKernel, Test.Services.Interfaces"
type="Test.Services.Impl.Kernel, Test.Services.Impl" >
<parameters>
<TestValue>42</TestValue>
</parameters>
</component>
</components>
<facilities>
<facility
id="CastleWcfItegration"
type="Castle.Facilities.WcfIntegration.WcfFacility, Castle.Facilities.WcfIntegration">
</facility>
</facilities>
</configuration>
La particolarità è che si è specificata la facility di CastleWcfIntegration, in questo modo si può hostare un servizio con il custom Host definito nella facility
using (DefaultServiceHost host = (DefaultServiceHost)new DefaultServiceHostFactory().CreateServiceHost(
typeof(IKernel).AssemblyQualifiedName, new Uri[0]))
{
Uri serviceAddress = new Uri("http://localhost:7601/Kernel");
Uri serviceMexAddress = new Uri("http://localhost:7601/Kernel/mex");
host.Description.Behaviors.Add(new ServiceMetadataBehavior());
host.AddServiceEndpoint(typeof(Test.Services.Interfaces.IKernel), new BasicHttpBinding(), serviceAddress);
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), serviceMexAddress);
host.Open();
Console.WriteLine("Host started");
System.Console.ReadKey();
}
L’unica differenza con gli esempi standard di WCF è che in questo caso l’host è di tipo DefaultServiceHost, definito in Castle.Facilities.WcfIntegration. Se lanciate il programma e provate ad invocare il servizio con il WcfTestClient potrete notare che il valore di ritorno del metodo Test è 42, ovvero il nostro servizio è stato risolto in maniera completamente automatica da Castle.
Alk.
Tags: Castle Windsor Wcf