thestralFeather7
thestralFeather7

Reputation: 519

Dependency Injection using Unity in ASP.NET

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.

Upvotes: 0

Views: 1366

Answers (1)

NightOwl888
NightOwl888

Reputation: 56909

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/

Upvotes: 2

Related Questions