Setting a named type as a dependency?

Jul 17, 2008 at 10:39 PM

I've attempted to register a factory with unity to provide named types. 

E.g.,

[...].RegisterFactory<IService>("NamedService", [delegate]);

And tried to configure a dependency (constructor-based injection) such that my factory will be called:

<type type="ServiceClient">

<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,

Microsoft.Practices.Unity.Configuration">

<constructor>

<param name="service" parameterType="IService">

<dependency name="NamedService"/>

</param>

</constructor>
</typeConfig>
</type>

However,  the factory does not get called.  As far as I can tell setting the name attribute on the dependency element has no effect. Has anyone used this attribute successfully?

Thanks for any help.

 

Jul 18, 2008 at 12:39 AM
Could you post a complete sample (a unit test would be great) that demonstrates the failure?

Jul 18, 2008 at 2:27 AM
I'm trying to anonymize it somewhat. But the basic logic is:

1) I have bootstrapper for the unity container that registers a factory where "container" is an IUnityContainer and WcfFactory is a factory for creating WCF dynamic proxies:

 private void RegisterProxyFactory(Type serviceType, String serviceClientName)
        {
            IStaticFactoryConfiguration isfc = container.Configure<StaticFactoryExtension>();
            Type isfcType = isfc.GetType();

            //  bMethodInfo methodInfo = isfcType.GetMethod("RegisterFactory", new Type[] { typeof(FactoryDelegate) });
            MethodInfo methodInfo = isfcType.GetMethod("RegisterFactory", new Type[] { typeof(String), typeof(FactoryDelegate) });
            Type[] genericArguments = new Type[] { serviceType };

            MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);

            FactoryDelegate wcfresolve = uContainer => WcfFactory.CreateClient(serviceType, serviceClientName);
            //genericMethodInfo.Invoke(isfc, new object[] { wcfresolve });
            genericMethodInfo.Invoke(isfc, new object[] { serviceClientName, wcfresolve });
        }

This method is called with the full type name of IService and a name such as "Foo"

2. I have a type with a constructer that takes an instance of a service interface

        public ServiceClient(IService serviceProxy)
        {
            this.svc = serviceProxy;
        }

3. I configure the dependency injection for the type:

 <type type="ServiceClient">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
                                     Microsoft.Practices.Unity.Configuration">
              <constructor>
                <param name="serviceProxy" parameterType="IService">
                  <dependency name="Foo""/>
                </param>
               </constructor>
            </typeConfig>
          </type>

note that "IService" has an alias defined in config to the full type name.

4. I create the ServiceClient using the container's Resolve method.

I get an exception that looks like

{"Resolution of the dependency failed, type = \"ServiceClient\", name = \"\". Exception message is: The current build operation (build key Build Key[ServiceClient, null]) failed: The parameter serviceProxy could not be resolved when attempting to call constructor ServiceClient(ServiceNamsepace.IService serviceProxy). (Strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2)"}

with a nested exception that has a message like:

"The current build operation (build key Build Key[ServiceNamespace.IService, null]) failed: The current type, ServiceNamepace.IService, is an interface and cannot be constructed. Are you missing a type mapping? (Strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2)"

Note that "Foo" is not set for the name value.

If I register my factory without a name this works fine - the factory is invoked and a proxy gets created properly and is injected into ServiceClient.  This leads me to believe that the name attribute is not being used or it is being validated against some other part of the config file and is being discarded since it doesn't match a type name. I did try defining a dummy type of IService in the config file with the name "Foo" but it didn't seem to change anything.

Jul 18, 2008 at 9:51 PM
I'm sorry.  I retract my post.  Basically it was an RTFM. I wasn't explicitly reading in the config information as described.  Things are working correctly now and I am able to configure WCF proxies as dependencies dynamically based upon a combination of Unity and WCF config information using the dependency "name" attribute as the link between the two.

Sorry if I wasted any of your time.