views:

41

answers:

2

hi guys,

i'm trying to use unity to resolve an generic instance of the IChannelFactory<ISomeType> to create channels to a service i have written.

The problem is that the concrete version of this class ChannelFactory<ISomeType> takes the concrete type System.ServiceModel.Channels.Binding as a parameter.

My first problem was that it could not find System.ServiceModel but i resolved that by putting the super fully qualified name (including version number etc). So now i can break into the code but it blows up when i try to resolve an IChannelFactory

My config is as such:

      <!--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>          

The error i get is that it cannot construct the type because it is an interface, even though the mapping to a concrete type is clearly there. Notice i am trying to constrict the type resolution to specific types so it only works with IChannelFactory<ISomeType> and not IChannelFactory<ISomeOtherType>, for instance. perhaps this isn't ythe correct way to do things?

If i just try to resolve the Binding in isolation it says it cannot disambiguate from other constructors taking one parameter (even though i defined the param type to be string!)

Any ideas or pointers what i am doing wrong here peeps? Or perhaps even a solution ;-)

Thanks

A: 

You can configure a generic interface/implementation in this way:

<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>

more details on msdn - Configuration Support for Generics

onof
how would i constrain this to ICustomerAccountProvider though? because i eventually intend on having a number of channel factories for different types with different bindings, so i'm not sure this would work long term?
mr.nicksta
this work only if the ChannelFactory is a generic implementation of IChannelFactory. If you have several (not generic) channel factories you have to map each one to the specific implementation: `<type name="customerChannelFactory"type="System.ServiceModel.Channels.IChannelFactory`1[MyNameSpace.ICustomerAccountProvider], System.ServiceModel" mapTo="MyNameSpace.CustomerChannelFactory, System.ServiceModel">`
onof
this is intended to work with the generic `ChannelFactory<TChannel>`. I have tried your suggestion to no avail
mr.nicksta
A: 

after much searching it seems that this just may not be possible in unity 1.2? it seems that unity 1.2 does not support open generic types, this feature was introduced in unity 2.0.

see the following: http://davidhayden.com/blog/dave/archive/2008/03/25/UnityDependencyInjectionOpenGenericTypes.aspx

if anyone would like to prove otherwise, i'd be most welcome :-)

mr.nicksta
Did you notice the date on that blog post? It's 2008! That's talking about a new drop adding the feature in Unity 1.2
Chris Tavares
chris, unfortunately we're stuck using 1.1 so that is pertinent here. And there's no easy way i can change to using a newer version quickly :-(
mr.nicksta