Frédéric Colin
WCF : L’extensibilité par la pratique – L’exemple
Dans le précédent volet, je vous ai expliqué une partie des fondamentaux de l’extensibilité WCF. Je vous ai aussi décrit le fonctionnel d’un exemple plus complet que je vais maintenant concevoir et développer pour illustrer l’invocation d’opération.
Par Frédéric Colin publié le 13/09/2009 à 22:18, lu 1796 fois, 9 pages
 5 | Implémentation du processus porteur
C’est à ce niveau que se situe le gros du travail. En effet, c’est au chargement de ce processus que l’Assembly est générée via CodeDom. Voici le code du programme principal, lors du démarrage du processus porteur :

static void Main(string[] args)

{

    DynamicHost host = new DynamicHost();

 

    // Build Service Assembly

    Assembly memoryAssembly = host.GetContractAssembly();

 

    // Get all needed parameters

    String contractFullName = String.Format("{0}.{1}",

        ConfigurationManager.AppSettings["NamespaceToGenerate"],

        ConfigurationManager.AppSettings["FacadeName"]);

    String serviceFullName = String.Format("{0}.{1}", ConfigurationManager.AppSettings["NamespaceToGenerate"],

        ConfigurationManager.AppSettings["ServiceName"]);

    Type contract = memoryAssembly.GetType(contractFullName);

    Type service = memoryAssembly.GetType(serviceFullName);

 

    // Create the WCF Service Host

    ServiceHost sh = new ServiceHost(service);

    sh.AddServiceEndpoint(contract, new NetTcpBinding(),

        String.Format("{0}/{1}", ConfigurationManager.AppSettings["FacadeUrl"], contractFullName));

 

    // Add HttpGet Metadata

    ServiceMetadataBehavior metadataBehavior = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();

 

    if (metadataBehavior == null)

    {

        metadataBehavior = new ServiceMetadataBehavior();

        sh.Description.Behaviors.Add(metadataBehavior);

    }

 

    // Add metadata behavior to existing behaviors

    ServiceDebugBehavior serv = sh.Description.Behaviors.Find<ServiceDebugBehavior>();

    if (serv == null)

    {

        serv = new ServiceDebugBehavior();

        sh.Description.Behaviors.Add(metadataBehavior);

    }

 

    // Generate detailed faults. ONLY FOR DEBUG PURPOSE!

    serv.IncludeExceptionDetailInFaults = true;

 

    // {"HTTP could not register URL http://+:1111/THB.Sample.ServiceContracts.IFacade/HttpGetUrl/.

    // Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353

    // for details)."}

    // C:\Windows\system32>netsh http add urlacl url=http://+:1111/ user=bewise\fcolin

    // URL reservation successfully added

    metadataBehavior.HttpGetEnabled = true;

    metadataBehavior.HttpGetUrl = new Uri(String.Format(ConfigurationManager.AppSettings["HttpGetUrl"],

        contractFullName));

 

    // Add MexEndPoint

    sh.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(),

        String.Format(ConfigurationManager.AppSettings["MexTcpEndPoint"], contractFullName));

 

    sh.Open();

 

    Console.WriteLine("Facade service started!");

    Console.ReadLine();

 

    sh.Close();

}

Voici les éléments importants sur cette partie :
  • De nombreux paramètres utiles à la génération du Contrat de Service et de son implémentation sont stockés dans le fichier de configuration : espace de nom, nom du contrat de façade, nom du service, ainsi que de nombreux paramètres WCF habituellement contenus dans le tag « system.ServiceModel », ce que nous tenterons d’améliorer dans un prochain article.
  • La génération de l’Assembly en mémoire via CodeDom est réalisée via la classe « DynamicHost ».
  • La récupération du type du contrat de service et du type du service façade se fait en fonction des paramètres stockés en configuration à partir de l’Assembly générée en mémoire.
  • Vous noterez le codage en dur du binding (« netTcpBinding ») au niveau du EndPoint ajouté au service.
  • Afin de pouvoir ajouter un Mex EndPoint de Type Tcp, il faut créer un comportement de type « ServiceMetadataBehavior » pour autoriser la récupération des métadonnées sur http et pour en préciser l’url exacte. Cela se fait via une méthode générique très pratique sur la collection des comportements : « sh.Description.Behaviors.Find<TypeDuBehaviorRecherché>() ».
  • Vous noterez aussi l’ajout d’un comportement permettant d’inclure le détail des exceptions dans les fautes Wcf renvoyées au client. Bien entendu, j’ai ajouté cette partie juste pour me faciliter la tâche en cas de problèmes.
  • L’ajout d’un binding de type MexTcpBinding.
  • Vous noterez le manque d’une gestion d’exception.
Le reste du code est tout ce qu’il y a de plus basique et ne nécessite pas de commentaires particuliers.
 
» Démarrer une discussion