2009-12-07 4 views
7

Pour une boîte à outils qui utilise un service WCF distant, j'ai configuré un ChannelFactory<IMyService> dans UnityContainer.Configurer MaxItemsInObjectGraph d'un client WCF lors de l'utilisation de Unity

Maintenant, je veux configurer le comportement de point final de ce canal par le code (en utilisant l'unité) pour appliquer ce comportement:

<behaviors> 
    <endpointBehaviors> 
     <behavior name="BigGraph"> 
      <dataContractSerializer maxItemsInObjectGraph="1000000" /> 
     </behavior> 
     </endpointBehaviors> 
</behaviors> 

J'ai trouvé cet exemple sur MSDN (http://msdn.microsoft.com/en-us/library/ms732038.aspx)

ChannelFactory<IDataService> factory = new ChannelFactory<IDataService>(binding, address); 
foreach (OperationDescription op in factory.Endpoint.Contract.Operations) 
{ 
    vardataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior; 
    if (dataContractBehavior != null) 
    { 
     dataContractBehavior.MaxItemsInObjectGraph = 100000; 
    } 
} 
IDataService client = factory.CreateChannel(); 

mais maintenant je suis coincé en essayant de le faire dans une configuration Unity. Devrais-je me pencher sur l'interception?

+0

Pour l'instant je viens de construire l'usine, d'appliquer le comportement et de l'ajouter comme une instance au conteneur. – veertien

Répondre

1

Nous utilisons une extension de stratégie de construction dans l'unité pour ajouter des comportements sur l'hôte de service. Sur le client, nous avons une ServiceFactory.

/// <summary> 
/// Factory for creating application service proxies used on the workstation 
/// </summary> 
/// <typeparam name="TInterface">Interface for the service contract</typeparam> 
public class ServiceFactory<TInterface> where TInterface : class 
{ 
    private readonly List<IEndpointBehavior> m_Behaviors = new List<IEndpointBehavior>(); 

    /// <summary> 
    /// Add a behavior that is added to the proxy endpoint when the channel is created. 
    /// </summary> 
    /// <param name="behavior">An <see cref="IEndpointBehavior"/> that should be added</param>. 
    public void AddBehavior(IEndpointBehavior behavior) 
    { 
     m_Behaviors.Add(behavior); 
    } 

    /// <summary> 
    /// Creates a channel of type <see cref="CommunicationObjectInterceptor{TInterface}"/> given the endpoint address which 
    /// will recreate its "inner channel" if it becomes in a faulted state. 
    /// </summary> 
    /// <param name="url">The endpoint address for the given channel to connect to</param>. 
    public TInterface CreateChannel(string url) 
    { 
     // create the channel using channelfactory adding the behaviors in m_Behaviors 
    } 
} 

Ensuite, il faut configurer l'unité avec un InjectionFactory

new InjectionFactory(c => 
      { 
       var factory = new ServiceFactory<TInterface>(); 
       factory.AddBehavior(c.Resolve<IClientTokenBehavior>()); 
       return factory.CreateChannel(url); 
      }); 

En ce faisant de cette façon, vous pouvez également résoudre votre comportement par l'unité si vous avez des dépendances.

0

Je pense que vous devriez ajouter un niveau supplémentaire d'indirection afin que vous n'ayez pas besoin de gâcher l'interception ou quelque chose comme ça. Ce problème peut être facilement résolu en créant une nouvelle classe pour encapsuler le canal WCF. Par exemple,

public class MyServiceClient : IMyService 
{ 
    public MyServiceClient(IChannelFactory<IMyService> channel) 
    { 
    } 

    public void DoSomething() //DoSomething is the implementation of IMyService 
    { 
    //Initialize the behavior in the channel 
    //Calls channel.DoSomething 
    } 
} 
Questions connexes