Reputation: 34109
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
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
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