User friendly message required

May 8, 2010 at 11:52 AM

Hi,

I am configuring my Unity 2.0 container from a custom config file as below -

// Read unity configuration section information
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = "unity.config";
System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)config.GetSection("unity");

// Load the information in the container
_unityContainer.LoadConfiguration(section);

When there is some error in the config file, e.g. a spelling mistake in the Assembly Qualified Type Name, the exception that is thrown contains a message which does not help much to locate the error. It shows something like "The given assembly name or codebase was invalid". Now considering a reasonably large config file for production application, I think it is difficult to locate the actual line that's causing the error. Please see if it is possible to provide some kind of reference so that developer's can identify the line causing the error. You can use something like "Error in line: <actual string goes here>" or may be "Last successfully loaded type: typename" etc. in both the messages we would be able to identify the line causing error.

Please do something about this.

Thanks.

Rajarshi

 

 

 

Sep 30, 2010 at 11:37 AM

I agree, I spent like 4 hours scratching my head... finally found out that something is wrong in config file.

 

-Imran

Oct 1, 2010 at 4:13 AM

Believe me, I'd love to. However, in order for the type resolver stuff to work, we can't actually resolve a type until you configure the container. At that point, the line number information is long gone. In fact, I never get access to line numbers at all. The only time you get that is if the error occurs during deserialization, which we can't trigger on type names because of the type resolver stuff.

I'll still be thinking about it, but System.Configuration is really an awful API and gets in the way in SO many ways.

 

Oct 1, 2010 at 5:54 AM

Hi Chris,

Thanks for taking a look at the issue and at least understand the pain of the developers.

However, correct me if I am wrong; when we say "_unityContainer.LoadConfiguration(section);" are you not reading the type definitions in that section one line at a time? Of course you must be using very different techniques to trace the dependencies while resolving the type definitions, but don't you read the type definitions line by line from config file while adding the definitions to the container?

If you happen to read the config section (with type definitions) line by line, then I believe you can save the entire line as a string somewhere before attempting to load the type definition into the container. When some exception occurs, the message can at least post some additional information like "At the time of the error Unity was resolving <the string containing the erroneous type definition>" .

Believe me, as a developer that's what we do all the time when "The given assembly name or codebase was invalid" error comes. We check the already loaded types in the container and try to find out which was the last type successfully loaded in the container by going through the list of registrations in Watch window. We then go to the config file and check the next line and in most cases, that line contains the error.

Please check if this helps. I have become a fan of the DI pattern with Unity and almost all my deliveries are now based on loosely coupled design using Unity and I must mention two features that have greatly helped me -

1. Instance registration and resolution - I use this with Validation Application Block to overcome a limitation of the VAB. While using VAB with Windows Forms integrated validation with Validation Extension Provider control, when the field level validation fires from the TextBox control, all that we get in the DoValidate overridden method of a Custom Validator is the current value of the business object property with which the Custom Validator attribute is associated. We cannot get a reference to the complete business object in our custom validator class and there are scenarios when we need the complete business object in a property level Custom Validator. You can argue that the same can be achieved by using the Validator at Class/Object level, but then we loose the benefit of showing the Error Provider online, as soon as some value is entered in the Text box (a classic example is name Uniqueness validation). What we now do is after the business object is constructed we register the instance in Unity using named registration (e.g. "CurrentCustomerInstance") and in our Custom Validator we just get the named instance from the Unity container, that gives us access to the complete business object and any property of the object can then be checked. Of course, we unregister the named instance from the container at a suitable time. That was a real relief. Before this I was using a very crude method of extracting the Business Object from DataBindings collection from the ValidatedControl, using such Type Castings that made the validators very much strongly coupled to Windows Forms technology but I had no way. Now I bless you for instance registration.

2. Parameter Override - I was dying for it. We are following Presentation Model pattern very religiously and the layers that we have is like "Windows Form -> Presentation Model -> Business Object -> Data Access Layer with a strict top down visibility. The constructor dependency also goes like "Form <depends on> Presentation Model <depends on> Business Object <depends on> DAL"  Now suppose we have a list of Customers in one place with option for "Add/Edit/Delete" from the list. We were resolving the Custom Form object directly and all the P models, Business Objects and DALs were automatically created. What we were missing is how to instruct the form about the action that needs to be performed (e.g. Add, Edit etc.) that the user has already chosen from the List and in case if the action is edit, how to pass the ID value (or criteria in general) to edit. To solve this we created a UserAction object with two properties Action and Criteria. The Forms now depends (constructor depndency) on P Model and also on UserAction. So before resolving the form we are just creating a suitable UserAction object (via a Factory method on the UserAction object itself) and then passing the object as Parameter override while resolving the form. The Form stores the UserAction received via constructor in a field and in its Load event, invokes the action with the specified criteria if a valid UserAction object was passed.

These two features were really helpful and I was saying like "Thanks, Thanks, Thanks, Thanks, Thanks ....." to you guys.

Keep up the great work.

Rajarshi Basu Roy


 

Oct 1, 2010 at 4:56 PM
rajabasuroy wrote:

Hi Chris,

Thanks for taking a look at the issue and at least understand the pain of the developers.

However, correct me if I am wrong; when we say "_unityContainer.LoadConfiguration(section);" are you not reading the type definitions in that section one line at a time? Of course you must be using very different techniques to trace the dependencies while resolving the type definitions, but don't you read the type definitions line by line from config file while adding the definitions to the container?

Ok, I'll correct you. That's not how it works. Have you ever worked with System.Configuration? "We" are not reading the file at all. System.Configuration is, and it doesn't give me strings or line numbers. Instead it goes through a lot of gyrations internally and hands me back a populated UnityConfigurationSection object. I don't get line numbers or strings, I just get the deserialized object. There are some things (like bad XML or unknown attributes) that can be, and are, detected during this deserialization process. When those happen, you do get a line number because the config system knows where it is. But there are other kinds of errors that can't be detected until we actually go to configure the container. At that point line numbers are long gone.

I could theoretically change the type lookup so that it happens while the configuration is loaded. However, that would mean loading all the assemblies at config load time. Considering the massive number of requests I get for deferred loading of assemblies until something is actually resolved, and how many customers use config to specify type mappings that may not actually have been deployed yet, I think making that change would break a lot more people then it would help.

I feel the pain, believe me. This was the major reason for the improvement to the error messages from the resolve method, for example. When somebody around here was using Unity and got an error, they'd come to me to interpret it, and I was spending a significant amount of time doing this. Obviously something needed to be done. Similarly, something needs to be done around configuration error messages, I just don't know how to do it yet.

 

 

 

 

Oct 9, 2010 at 10:30 AM

Hi,

I noticed one thing with latest version of unity, it shows line with red underline in web.config file if something is wrong with refered assambly, that makes things easier.

But you don't get that red underline in app.config file, has this anything to do with unity or is it something VS/resharper thing?

 

-Imran

 

Oct 11, 2010 at 2:40 AM

I get red squiggles in app.config files all the time. Does your Unity section in the app.config file have the xmlns attribute correctly applied?