2010-09-21 8 views
2

J'essaie d'utiliser l'unité pour résoudre une instance générique du IChannelFactory<ISomeType> pour créer des canaux à un service que j'ai écrit.configuration de l'unité ouvrir les types génériques

Le problème est que la version concrète de cette classe ChannelFactory<ISomeType> prend comme paramètre le type de béton System.ServiceModel.Channels.Binding.

Mon premier problème était qu'il ne pouvait pas trouver System.ServiceModel mais j'ai résolu cela en mettant le nom super qualifié (y compris le numéro de version, etc.). Alors maintenant, je peux briser dans le code, mais il explose lorsque je tente de résoudre un IChannelFactory

Ma config est en tant que tel:

 <!--binding--> 
     <type name="customerBinding" type="System.ServiceModel.BasicHttpBinding, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> 
     <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration"> 
      <constructor> 
      <param name="configurationName" parameterType="System.String"> 
       <value value="CustomerAccountService" /> 
      </param>     
      </constructor> 
     </typeConfig> 
     </type> 

     <!-- customer account channel factory --> 
     <type name="customerChannelFactory" 
      type="System.ServiceModel.Channels.IChannelFactory`1[[ServiceContracts.Customer.ICustomerAccountProvider, ServiceContracts.Customer]], System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" 
      mapTo="System.ServiceModel.ChannelFactory`1[[ServiceContracts.Customer.ICustomerAccountProvider, ServiceContracts.Customer]], System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> 
     <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration"> 
      <constructor> 
      <param name="binding" parameterType="System.ServiceModel.Channels.Binding, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> 
       <dependency name="customerBinding" /> 
      </param> 
      </constructor> 
     </typeConfig> 
     </type>   

L'erreur que je reçois est qu'il ne peut pas construire le type parce qu'il est une interface, même si le mappage à un type concret est clairement là. Notez que j'essaie de restreindre la résolution de type à des types spécifiques, donc cela ne fonctionne qu'avec IChannelFactory<ISomeType> et pas IChannelFactory<ISomeOtherType>, par exemple. Peut-être que ce n'est pas la bonne façon de faire les choses?

Si j'essaie juste de résoudre le Binding en vase clos, il dit qu'il ne peut pas lever l'ambiguïté d'autres constructeurs qui prennent un paramètre (même si je défini le type de param être string!)

Toutes les idées ou des pointeurs ce que je fais mauvais peeps ici? Ou peut-être même une solution ;-)

Merci

+0

Je suis heureux de voir que je ne suis pas le seul qui ne peut jamais comprendre ce qui passe chaque fois que j'essaye quelque chose de non-trivial avec Unity! – fearofawhackplanet

+0

haha ​​je lisais juste ta question sur l'unité et les génériques il y a deux secondes! belle référence de l'ennemi public d'ailleurs :-) – WickyNilliams

+0

Êtes-vous résoudre avec le nom de l'enregistrement? –

Répondre

0

après beaucoup de recherches, il semble que cela peut ne pas être possible dans l'unité 1.2? il semble que l'unité 1.2 ne supporte pas les types génériques ouverts, cette fonctionnalité a été introduite dans unity 2.0.

voir les éléments suivants: http://davidhayden.com/blog/dave/archive/2008/03/25/UnityDependencyInjectionOpenGenericTypes.aspx

si quelqu'un voudrait prouver le contraire, je serais le bienvenu :-)

+0

Avez-vous remarqué la date sur ce blog? C'est 2008! Cela parle d'une nouvelle baisse ajoutant la fonctionnalité dans Unity 1.2 –

+0

chris, malheureusement, nous sommes bloqués en utilisant 1.1, ce qui est pertinent ici.Et il n'y a pas de moyen facile que je peux changer pour utiliser une version plus récente rapidement :-( – WickyNilliams

0

Vous pouvez configurer une interface générique/mise en œuvre de cette manière:

<type name="customerChannelFactory" 
      type="System.ServiceModel.Channels.IChannelFactory`1, System.ServiceModel" 
      mapTo="System.ServiceModel.ChannelFactory`1, System.ServiceModel"> 
     <typeConfig> 
      <constructor> 
      <param name="binding" parameterType="System.ServiceModel.Channels.Binding, System.ServiceModel"> 
       <dependency name="customerBinding" /> 
      </param> 
      </constructor> 
     </typeConfig> 
     </type> 

plus de détails sur msdn - Configuration Support for Generics

+0

comment devrais-je contraindre cela à ICustomerAccountProvider si? parce que j'ai finalement l'intention d'avoir un certain nombre d'usines de canaux pour différents types avec différentes liaisons, donc je ne suis pas sûr que cela fonctionnerait à long terme? – WickyNilliams

+0

ce travail uniquement si ChannelFactory est une implémentation générique de IChannelFactory. Si vous avez plusieurs fabriques de canaux (non génériques), vous devez mapper chacune d'entre elles sur l'implémentation spécifique: '' – onof

+0

Ceci est prévu pour fonctionner avec le 'ChannelFactory 'générique. J'ai essayé votre suggestion en vain – WickyNilliams