Using Buildup in ASP.NET

Oct 23, 2009 at 5:24 PM
Edited Oct 23, 2009 at 5:25 PM

I'm new to Unity.

What I'm trying to do is use BuildUp to inject dependencies into my page, following the guidance of several different blogs on the topic. During testing, I want to get the default implementation (MockAppData), but in production, I want to get RealAppData instead.

The code below works to get the default implementation of IappData, but when I try to get the named implementation ("Production"), I still get the default instance. Obviously I don't understand BuildUp!

Is there some better way for me to go about what I'm trying to do?

Thanks in advance,

R.L.

// in global.asax.cs

public void Application_Start(object sender, EventArgs e)
{
// Register the relevant types for the // container here through classes or configuration if (_container == null)
{
_container = new UnityContainer()
.RegisterType<IAppData, MockAppData>()
.RegisterType<IAppData, RealAppData>("Production");
}
}

// in a separate class file
public
abstract class BasePage<T> : Page where T : class { [Dependency] public IAppData AppData {get; set;}

protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
InjectDependencies();
}

protected virtual void InjectDependencies()
{
var context = HttpContext.Current;
if (context == null) return;

var accessor = context.ApplicationInstance as IContainerAccessor;
if (accessor == null) return;

var container = accessor.Container;
if (container == null) {throw new InvalidOperationException("No Unity container found");}

container.BuildUp(this, "Production"); // expected this to find named registration, but it doesn't }
}

 

Dec 18, 2009 at 12:49 AM

Names aren't recursive - it's going to BuildUp your page based on your current type, looking for a registration for BasePage<T>, "Production". It doesn't find one (I assume) so it then uses the default. Which has [Dependency] on the AppData property, which results in injecting the default type for IAppData.

You're better off using the API to configure the property to be injected, this way you can specify which name to use in which situation. Something like this:

 

container
    .RegisterType(typeof(BasePage<>),
        new InjectionProperty("AppData"))
    .RegisterType(typeof(BasePage<>), "Production",
        new InjectionProperty("AppData", new ResolvedParameter<IAppData>("Production"));

    This registers the default to inject the default value for AppData, and when resolving with the name Production resolve Production in the appdata.