When using ASP.NET MVC plus Entity Framework, and trying to implement a generic repository and a generic service, and have everything resolved by Unity Ioc:
I am trying to get Unity Ioc to inject a generic service into the controller using parameter injection, but the type resolving is failing with this this error message:
Activation error occured while trying to get instance of type
ISupplierService The current build operation (build key Build
Key[MyApp.Services.Implementation.SupplierService, null]) failed:
Activation error occured while trying to get instance of type
IGenericRepository1, key \"\" Resolution of the dependency failed:1[Entities.Supplier],
The current type,
MyApp.Repository.Interfaces.IGenericRepository
is an interface and cannot be constructed. Are you missing a type
mapping? (Strategy type BuildPlanStrategy, index 3)
I can understand that the error message means that it is trying to create an instance of IGenericRepository when instead I am actually trying to get it to create an instance of SupplierService, but I do not see why it is resolving this way. As per initial answers it could be because the types are not registered
The controller’s service injection is:
public class SupplierController : Controller
{
private readonly ISupplierService _service;
public SupplierController() : this (null) { }
public SupplierController(ISupplierService service)
{
_service = service;
}
// .. injection fails, service is NULL
}
Supplier service is an empty interface plus empty class (which could have custom methods added later if needed)
public partial interface ISupplierService : IGenericService<Supplier> {}
IGenericService simply resurfaces the IGenericRepository’s methods:
public interface IGenericService<T> : IDisposable where T : BaseEntity {}
In Global.asax.cs the IoC container is created by
var container = new UnityContainer();
var uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
string path = System.IO.Path.GetDirectoryName(uri.AbsolutePath);
var assemblyPaths = new List<string>
{
Path.Combine(path, "MyApp.Repository.Interfaces.dll"),
Path.Combine(path, "MyApp.Repository.Implementation.dll"),
Path.Combine(path, "MyApp.Services.Interfaces.dll"),
Path.Combine(path, "MyApp.Services.Implementation.dll")
};
container
.ConfigureAutoRegistration()
.LoadAssembliesFrom(assemblyPaths)
.ExcludeSystemAssemblies()
.Include(If.Any, Then.Register())
.ApplyAutoRegistration();
var serviceLocator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
experimented with UnityAutoRegistration while the latest release was still “fresh” and I was not happy with it. The TecX project on codeplex contains a port of the StructureMap config engine which gives you support for conventions that should make your life a lot easier.
Something like
should register all of your Interface/Service and Interface/Repository pairs. The convention registers
SupplierServiceas the implementation ofISupplierServiceetc.The additional call to
RegisterTypewith the two open generic types (IGenericRepositoy<>andGenericRepository) maps your generic repository interface to the generic repository class. Unity will close the type definition automatically for you (i.e.IGenericRepository<Supplier>will be mapped toGenericRepository<Supplier>).