Unity IoC resolving a Generic Service plus Generic repository

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: The current type, MyApp.Repository.Interfaces.IGenericRepository1[Entities.Supplier], 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);

Answers


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

ConfigurationBuilder builder = new ConfigurationBuilder();
builder.Scan(s =>
{
  s.AssembliesFromApplicationBaseDirectory();
  s.With(new ImplementsIInterfaceNameConvention());
}
var container = new UnityContainer();
container.AddExtension(builder);
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<>));
var serviceLocator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);

should register all of your Interface/Service and Interface/Repository pairs. The convention registers SupplierService as the implementation of ISupplierService etc. The additional call to RegisterType with the two open generic types (IGenericRepositoy<> and GenericRepository) 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 to GenericRepository<Supplier>).


Need Your Help

What is the best way to connect two users with credit card for payments on the web site?

e-commerce paypal authorize

What is the best way to allow one site user to pay to another user, through web site using credit card?