Newbie config file problem

Apr 15, 2008 at 5:49 AM
I am trying to determine whether I should switch from swing to Unity, but I seem to be having a problem setting dependencies for constructors. If anyone could point me in the right direction I would really appreciate this, I have scoured the docs and played with endless variations of the config file.

Everything works fine if I delete the constructor, but even with a simple string it blows up.

I have a simple class called KeController which implements an interface IKeController.

The constructor is:
Public Sub New(ByVal s As String)
s1 = s
End Sub

the app.config section is:

<type type="UnityTest1.IKeController" mapTo="UnityTest1.KeController">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
<param name="s" parameterType="string">
<value value="contoso"/>
<dependency />

The errors are:
Top Level : Resolution of the dependency failed, type = "KeController", name = "". See the InnerException for more details.

Inner Exception: The current build operation failed on strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2 for build key Build Key[System.String, null]

Inner Exception: The current build operation failed on strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2 for build key Build Key[System.SByte*, null]

Inner Exception: Invalid type owner for DynamicMethod.
Apr 15, 2008 at 6:52 AM
I think the error is here:

<value value="contoso"/>
<dependency />

Remove the <dependency /> line and it should start working. You need either <value> to specify a value to give, or <dependency> to tell it to resolve the parameter's value through the container. Last one wins, so it's resolving through the container.

We should probably make this an exception.
Apr 15, 2008 at 7:35 AM
Edited Apr 15, 2008 at 7:37 AM
I was wondering about that, it seemed a bit odd, so I tried removing it. No luck. BTW - that is how it is in the documentation.

I don't have IKeController or KeController anywhere else in the app.config, which is just a cut/paste of the sample in the CHM

The code is very simple:
Dim myContainer As IUnityContainer = New UnityContainer()
myContainer.RegisterType(Of IKeController, KeController)()
Dim myInstance As KeController = myContainer.Resolve(Of IKeController)()


I still get the same errors.

My entire app.config is:

<?xml version="1.0" encoding="utf-8" ?>

<section name="unity"
Microsoft.Practices.Unity.Configuration, Version=,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />


<container name="Default">
<type type="UnityTest1.IKeController" mapTo="UnityTest1.KeController">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
<param name="s" parameterType="string" >
<value value="contoso"/>
Apr 15, 2008 at 8:57 PM
Edited Apr 20, 2008 at 8:57 AM
Thanks for the docs error report; I'll try to get it fixed for the next rev.

The error in your code is that you're not actually reading the configuration anywhere. Newing up the container does not automatically read the app.config file; you must do it manually.

In C#, you need to do this:
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("Unity");
The equivalent VB is (I think I'm a little rusty):
Dim container as IUnityContainer = new UnityContainer()
Dim section as UnityConfigurationSection
section = DirectCast(ConfigurationManager.GetSection("unity"), UnityConfigurationSection)
Then you can do:

container.Resolve(Of IKeController)()

And it should work. You don't need to do the RegisterType, as that's already taken care of in the configuration file.
Apr 20, 2008 at 7:14 AM
Thanks for the tip! I was beginning to suspect something like that. I remembered glancing at that section of the CHM, but didn't initially think it was necessary.

Unfortunately, I'm still having some related problems - If anyone has any pointers I would be very, very appreciative.

1. The Section object does not appear to have a .Resolve method. Was it changed recently? Should that line read:

2. I can inject a string into the constructor but do not seem to be able to figure out how to inject a custom object. The contructor is simply:
Public Sub New(ByVal view As View1)

and the config section is:

<type type="UnityTest2.Controller1,UnityTest2" >
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
<param name="view" parameterType="UnityTest2.View1" >
<value />

the error is:
Could not load type 'UnityTest2.View1' from assembly 'Microsoft.Practices.Unity.Configuration, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.

I've tried every permutation of attributes and values I can think of, including:

<param name="view" propertyType="UnityTest2.View1" parameterType="UnityTest2.View1" > <-- "Unrecognized attribute 'propertyType"
<value type="UnityTest2.View1" /> <-- Same error as without the type attribute
replacing <value/> with <dependency/> :
<param name="view" parameterType="UnityTest2.View1" >
<dependency type="UnityTest2.View1"/>

Both View1 and Controller1 are definitely loading fine as long as I am only injecting strings into the constructors. I suspect it is something the <dependency/> section, but it beats me.

I have some other questions but I will scores the boards before posting them in different threads.

Thanks in advance for any tips/pointers

Apr 20, 2008 at 8:53 AM
Edited Apr 20, 2008 at 8:57 AM
Sorry about the "section.Resolve" thing - that line should have been "container.Resolve". That probably makes a lot more sense. ;-) I have edited my above message to fix the stupid typos (and add all new, even stupider ones).

As for injecting a custom object, I assume you want that custom object created by the container? In that case, it's a dependency, not a value, so you'd configure it something like this:

<param name="view" parameterType="UnityTest2.View1, UnityTest2" >
  <dependency />

Two things to notice here. First, the full name of the parameterType is needed, including the assembly name. Otherwise it'll look in the Unity.Configuration assembly for the type, which explains the error you're getting. Second, <dependency /> tells the container to resolve the value through the container.

I haven't tried these yet, but it should be close to right (off the top of my head). I think your main problem was not having the full type name (including the assembly name).

Out of curiosity, what are your reasons for thinking about switching from Spring? Is it that Unity is from Microsoft, dissatisfaction with Spring, something nice in Unity, or other? We've been telling people all along that if you're happy with your current DI container, there's no reason to switch. So I'm wondering if there's a specific reason you're looking at Unity?

Not that I'd mind if you switched, but I hope it's for more than "It's from Microsoft".
Apr 20, 2008 at 6:40 PM
Thanks again! I'll try out the config recommendations later this afternoon, but I thought I would answer your question.

First, I can't say I have switched. I am exploring and am optimistic. Is it because it is from Microsoft? LOL, no, no, no. Although I am a microsoft fan the words "microsoft" and "open source" in the same sentence never really did anything more than make me chuckle until recently. However I did keep my eyes on the p&p group. It was obvious from the beginning that they were doing some interesting things and were forward looking. Things like the SCSF were great first steps. And the combination of guidance along with code is something that is sorely needed. I really liked their attempts to merge the two. Eventually, I became a big fan theirs.

In short, the reason I am optimistic about Unity is because of the P&P group.
Apr 21, 2008 at 6:13 AM
Works like a charm!
I kept trying to use all sorts of attributes in the <dependency /> tag. None required.

Perhaps to give something back, I could clean up my code, add some comments and upload it for others to learn from. Is it possible to upload attachments? Is that something you think would be useful?

Thanks a million.