I'm using Unity 4 (through NuGet) with ASP.NET MVC 5. I've modified all my controller and business classes to receive their dependencies as interfaces through their constructors.
The boostrapper class contains the following code:
public class Bootstrapper
{
public static IUnityContainer UnityContainer { get; set; }
public static void Initialize()
{
InitializeUnity();
RegisterTypes();
}
private static void InitializeUnity()
{
UnityContainer = UnityConfig.GetConfiguredContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(UnityContainer));
}
private static void RegisterTypes()
{
new Core.Bootstrapper().RegisterTypes(UnityContainer);
}
}
The content of Core.Bootstrapper().RegisterTypes is as follows:
public IUnityContainer RegisterTypes(IUnityContainer container)
{
// Register repositories
container.RegisterType<IRepository, Repository>()
.RegisterType<IBdeRepository, BdeRepository>()
.RegisterType<IDocumentRepository, DocumentRepository>()
.RegisterType<IHampRepository, HampRepository>()
.RegisterType<IReportsRepository, ReportsRepository>()
.RegisterType<ITransactionRepository, TransactionRepository>();
// Register commands
container.RegisterType<IBaseCommand, BaseCommand>()
.RegisterType<IDailyLetterInfoUpdate, DailyLetterInfoUpdate>()
.RegisterType<IDailyReconciliation, DailyReconciliation>()
.RegisterType<InsertNewRows, InsertNewRows>()
.RegisterType<IOrderDailyLM023, OrderDailyLM023>()
.RegisterType<IOrderMonthlyLM012, OrderMonthlyLM012>()
.RegisterType<IOrderMonthlyLM014, OrderMonthlyLM014>()
.RegisterType<IPerformMonthlyRecastStatusUpdate, PerformMonthlyRecastStatusUpdate>()
.RegisterType<IUpdateReissuedRecasts, UpdateReissuedRecasts>();
// Register utility types
container.RegisterType<ICsvExporter, CsvExporter>()
.RegisterType<ILogger, Logger>();
return container;
}
Finally, both UnityConfig.cs and UnityMvcActivator.cs remain unmodified from what they were when they were first installed by the NuGet package.
When I start my MVC application, I am confronted with the following error message:
Resolution of the dependency failed, type = "System.Web.Mvc.ITempDataProviderFactory", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, System.Web.Mvc.ITempDataProviderFactory, is an interface and cannot be constructed. Are you missing a type mapping?
The class it mentions appears to be something internal to MVC, itself, which leads me to believe that I've either missed something in configuring Unity, or that I've whacked something in doing so. For the life of me, however, I can't figure out what it is, despite having consulted virtually every question I can find regarding the error message on StackOverflow. (None of the proposed solutions have resolved the issue so far, but it's quite likely I've missed something.)
Can anyone see something I've overlooked? What am I doing wrong?
UPDATE:
The exception is thrown here:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes(); // Exception thrown on this line.
}
I found the solution to my particular scenario, and it was kind of surprising.
I had to roll my own DependencyResolver class and use it in lieu of the MVC resolver provided by Unity. The resolver I wrote is as follows:
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
/// <summary>
/// Resolves dependencies against the current DI container.
/// </summary>
public class UnityDependencyResolver : IDependencyResolver
{
/// <summary>
/// The container
/// </summary>
private readonly IUnityContainer container;
/// <summary>
/// Initializes a new instance of the <see cref="UnityDependencyResolver"/> class.
/// </summary>
/// <param name="container">The container.</param>
public UnityDependencyResolver(IUnityContainer container)
{
this.container = container;
}
/// <summary>
/// Resolves an instance of the default requested type from the container.
/// </summary>
/// <param name="serviceType">The <see cref="Type"/> of the object to get from the container.</param>
/// <returns>The requested object, if it can be resolved; otherwise, <c>null</c>.</returns>
public object GetService(Type serviceType)
{
return this.container.IsRegistered(serviceType)
? this.container.Resolve(serviceType)
: null;
}
/// <summary>
/// Resolves multiply registered services.
/// </summary>
/// <param name="serviceType">The type of the requested services.</param>
/// <returns>The requested services.</returns>
public IEnumerable<object> GetServices(Type serviceType)
{
return this.container.ResolveAll(serviceType);
}
}
The most important part was the implementation of GetService: It must return null
if it can't resolve a type, otherwise, MVC goes belly-up and throws an exception with the message, "XXX is an interface, and can't be constructed. Are you missing a binding?"
This, of course changed the behavior of this line of code in Bootstrapper.cs:
DependencyResolver.SetResolver(
new UnityDependencyResolver(UnityContainer));
It uses the local implementation instead of the default Unity implementation.
What's weird about this is that the sample app I'm drawing from works locally on my machine, and it isn't using a custom resolver. It works fine without this class. I don't know why this worked, and that's troubling (I prefer deterministic answers to questions), but at this point I'm just happy I can get back to work.