0

I have a pretty straight forward setup.

namespace ObjectNamespace
{
    public class CustomProcessor : ICustomProcessor<myObject>
    {
        public CustomProcessorResult Execute(myObject Data)
        {
            try
            {
                var container = new UnityContainer();
                // UnityConfigurationSection section = new UnityConfigurationSection();

                var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
                // this gives Microsoft.Practices.Unity.Configuration.UnityConfigurationSection
                section.Containers.Default.Configure(container);

                var configuration = Container.Resolve<ICustomProcessorConfiguration>(); 
                var emailer = container.Resolve<IEmailManager>(); 
                var reportGenerator = container.Resolve<IReportGenerator>();  
            }
            catch (Exception e)
            {
                Trace.WriteLine("It failed while trying to initialize the DI componenets");
                throw;
            }

The error message is of a null reference exception . It's showing that at

section.Containers.Default.Configure(Container);

my section throws me back the value I had in the web.config file which is commented on that line (Microsoft.Practices.Unity.Configuration.UnityConfigurationSection)

I'm at my wits end just to implement this Execute method. I don't know why it's giving me an error for null reference. The Container is supposed to be configured by the UnityConfigurationSection.

This is my web.config file inside the <configSections> tag

<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, myCustom.dll" />

As far as I know that's how to resolve and bind to an interface. Am I doing something wrong?

Are there any alternative ways of setting up a section? or configuring the container? before resolving it?

EDIT : After the one answer provided below I tried to skip the section portion of the code , but the DI components are still not being initialized as it says that the "header comments" are missing which is what it's looking at in the config files. That's the way the application is set up. So I'm guessing grabbing the value from the config "unity" section is essential . any way I can incorporate the section part in my code ? Make it configure my Containers ?

I have mapped my <unity> tags for DI in myApp.cfg file here ( eg: for the email )

<type type= "myProject.Interfaces.IEmailManager, mySolution (dll name)"
    mapTo="myProject.EmailManager,  mySolution (dll name)" >
<lifetime type="singleton"/>
</type>

So after another suggestion , I stripped out all the XML unity based integration code and I'm getting a ResolutionFailedException from Unity. I have taken down all the xml integration and registered like suggested but now I am getting a build operation failed, Required attribute , 'header comment' not found. I even had an alias set up in myApp.cfg as a typeAlias for ControlledLifetimeManager and I've taken that out too. no unity references remain and this is the error I am getting. It's trying to read from web.config line 43 and giving me this error. There isn't any registration of header comment that is needed or that I know of.

4
  • 1
    You may want to add the related content (i.e. the "unity" section) from your config file to the question. Commented May 2, 2015 at 4:12
  • Type portion of the section looks wrong - I doubt UnityConfigurationSection is defined in your "myCustom.dll"... Commented May 2, 2015 at 4:21
  • @AlexeiLevenkov myCustom.dll has a bundle of a lot of other dlls. I have been given that to work with. The section returns as intended . Atleast as a string ! Commented May 2, 2015 at 4:58
  • @thestralFeather7 merging assemblies and reflection-based code is hard to get right. I'm afraid you'd need to post way too much information for this to be answerable on SO... Commented May 2, 2015 at 5:02

1 Answer 1

2

Are there any alternative ways of setting up a section? or configuring the container? before resolving it?

Yes. There is no need to use XML configuration unless your application requires components to be changed around without a recompile (which is not normally the case). XML configuration is now mostly considered to be an obsolete way to configure a DI container. It is brittle and time consuming to maintain compared to code-based configuration.

You can instead use the fluent API and/or container extensions to configure your components. Here is an example of the fluent API:

// Begin composition root
var container = new UnityContainer();

// This is the equivalent to the XML registration 
// code you show in your question 
container.RegisterType<IEmailManager, EmailManager>(new ContainerControlledLifetimeManager());
// End composition root

IEmailManager emailManager = container.Resolve<IEmailManager>();

The composition root should be set up at the entry point of your application. In ASP.NET that would be in the Application_Start event of the Global.asax file.

Of course, you will need to strip out any code that you have set up for XML configuration + any XML elements that you have set up for Unity or you may get errors from Unity trying to load those elements.

Additional information:

http://blog.ploeh.dk/2011/07/28/CompositionRoot/

Sign up to request clarification or add additional context in comments.

9 Comments

Amen +1. And even if you need dependencies to change after deployment, there is hardly ever a need to define fully qualified type names in your config file. This is brittle and error prone. Simple configuration switches do fine most of the time.
@NightOwl888 When I'm trying to build it like this it says that the "header comments" are missing which is what it's looking at in the config files. That's the way the application is set up. So I'm guessing grabbing the value from the config "unity" section is essential . any way I can incorporate the section part in my code ?
@thestralFeather7 - The default container does not look for a configuration file at all. So, the error you are getting is related to another part of your setup. I would venture to guess it has something to do with resolving an ICustomProcessor or an ICustomProcessorConfiguration, but since I have never set up XML configuration I don't know exactly what the cause is. All I can tell you is make sure you strip out all of the XML configuration code. Your composition root should be set up at the entry point of the application.
I don't need to write a constructor I believe. I am just implementing an interface. Am I right ?
It depends on if your component has dependencies (if you have dependencies, they should be injected in the constructor). But that seems unrelated to your original question.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.