LP13
LP13

Reputation: 34109

Unity: The current type,'XXXXX', is an interface and cannot be constructed. Are you missing a type mapping?

I have multiple types that are derived from the same interface. And I am using Unity IOC container to register the types

public interface IService
{
}

public class ServiceA : IService
{
}

public class ServiceB : IService
{

}

public class ServiceC : IService
{

}

If I register these types as below

        container.RegisterType<IService, ServiceA>("NameA");
        container.RegisterType<IService, ServiceB>("NameB");
        container.RegisterType<IService, ServiceC>("NameC");

then I can resolve types as below without any issue.

    var service = container.Resolve<IService>("NameA");

However I am getting list of types that needs to be register with container from outside. (lets assume from text file). So I need to register only those types that are in the provided list.

public class Program
{
    public static void Main()
    {
        // i will be getting this  dictionary values from somewhere outside of application
        // but for testing im putting it here
        var list = new Dictionary<string, string>();
        list.Add("NameA", "ServiceA");
        list.Add("NameB", "ServiceB");
        list.Add("NameC", "ServiceC");


        var container = new UnityContainer();
        var thisAssemebly = Assembly.GetExecutingAssembly();

        //register types only that are in the dictionary
        foreach (var item in list)
        {
            var t = thisAssemebly.ExportedTypes.First(x => x.Name == item.Value);
            container.RegisterType(t, item.Key);
        }

        // try to resolve. I get error here
        var service = container.Resolve<IService>("NameA");
    }
}

I am getting exception

An unhandled exception of type 'Microsoft.Practices.Unity.ResolutionFailedException' occurred in Microsoft.Practices.Unity.dll

Additional information: Resolution of the dependency failed, type = "ConsoleApplication1.IService", name = "NameA".

Exception occurred while: while resolving.

Exception is: InvalidOperationException - The current type, ConsoleApplication1.IService, is an interface and cannot be constructed. Are you missing a type mapping?


At the time of the exception, the container was:

Resolving ConsoleApplication1.IService,NameA

For some valid reasons i do not want to use Unity's register by convention option, or Unity's configuration file option to register types. I would like to register them based on the list I have.

Upvotes: 2

Views: 4629

Answers (2)

KamalDeep
KamalDeep

Reputation: 834

You are incorrectly using Dependency Injection. The proper way is to have your controllers take the dependencies they need and leave to the dependency injection framework inject the concrete instances. Find more info here.

    public class HomeController: Controller
    {
       private readonly ISettingsManager settingsManager;
       public HomeController(ISettingsManager settingsManager)
    {
        this.settingsManager = settingsManager;
    }

    public ActionResult Index()
    {
        // you could use the this.settingsManager here
    }
}

Upvotes: 0

Legends
Legends

Reputation: 22672

You forgot to specify a mapping IYourInterface --> YourClass

This works:

namespace ConsoleApplicationGrbage
{
class Program
{
    static void Main(string[] args)
    {
        var container = new UnityContainer();

        var list = new Dictionary<string, string>();
        list.Add("NameA", "YourClass");

        var thisAssemebly = Assembly.GetExecutingAssembly();
        var exT = thisAssemebly.ExportedTypes;
        //register types only that are in the dictionary
        foreach (var item in list)
        {
            var typeClass = exT.First(x => x.Name == item.Value);
            var ivmt = Type.GetType("ConsoleApplicationGrbage.IYourInterface");
            // --> Map Interface to ImplementationType
            container.RegisterType(ivmt, typeClass, item.Key);
            // or directly:
            container.RegisterType(typeof(IYourInterface), typeClass, item.Key);    
        }

        var impl = container.Resolve<IYourInterface>("NameA");
    }
}


public interface IYourInterface
{
}

public class YourClass: IYourInterface
{

}

}

Upvotes: 0

Related Questions