NKD
NKD

Reputation: 1049

Unity bootstrapper for ASP.NET MVC (by convention) not able to construct interfaces in a different project

I have the structure like so:

I have unity by convention setup in MyWork.Web project. It works fine when I leave Service.cs and IService.cs under MyWork.BLL. I'm trying to move IService.cs to MyWork.Interfaces for organization and decoupling. This way when working on the web project, all I have to worry about is coding against interface and add the using statment for MyWork.Interfaces. However, if I attempt to move IService.cs to the interface project, Unity by convention no longer works. Anyone know if this is possible? Do I have to always keep the interface and its implementation under the same project in order for Unity by convention to work properly? Here is my code for Unity by convention:

public static void RegisterTypes(IUnityContainer container)
    {
            container.RegisterTypes(
            AllClasses.FromLoadedAssemblies(),
            WithMappings.FromMatchingInterface,
            WithName.Default);
    }

Here is the error:

The current type, MyWork.Interfaces.IService, is an interface and cannot be constructed. Are you missing a type mapping?

Update:

UnityConfig.cs under App_Start of MyWork.Web

namespace MyWork.Web.App_Start
{
public class UnityConfig
{
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    public static IUnityContainer GetConfiguredContainer()
    {
        return container.Value;
    }

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<ICalculatorService, Interfaces.ICalculatorService>(); // added this per suggested answer

        container.RegisterTypes(
            AllClasses.FromLoadedAssemblies(),
            WithMappings.FromMatchingInterface,
            WithName.Default);
    }
}

}

Upvotes: 1

Views: 301

Answers (1)

Steven
Steven

Reputation: 172696

I bet the MyWork.Interfaces assembly hasn't been loaded yet. Unity's FromLoadedAssemblies call simply calls AppDomain.CurrentDomain.GetAssemblies() which by definition only returns assemblies that are loaded (not all referenced assemblies!).

There are two options here:

  1. Reference a type in the MyWork.Interfaces assembly explicitly inside your RegisterTypes methods. This ensures the assembly gets loaded.
  2. Call System.Web.Compilation.BuildManager.GetReferencedAssemblies() before calling container.RegisterTypes. The GetReferencedAssemblies() call will load all assemblies that are located in the web applications /bin folder. This will ensure that not only your Interfaces project, but all projects are loaded.

Upvotes: 1

Related Questions