David Aleu
David Aleu

Reputation: 3942

Unity not resolving repository

I have the classes below:

SuppliersRepository.cs (with the interface defining the method):

    public class SuppliersRepository : BaseRepository,ISuppliersRepository
    {
        public IEnumerable<Supplier> GetSuppliersByCoordinates(double latitude, double longitude)
        {
            using (IDbConnection connection = OpenConnection())
            {
                const string query = "SELECT ID=SupplierID,Name=Suppliername FROM suppliers WHERE dbo.Distance(@latitude,@longitude,latitude,longitude) < 15 AND latitude IS NOT NULL AND longitude IS NOT NULL";
                return connection.Query<Supplier>(query, new { latitude = latitude,longitude=longitude });
            }
        }

    }

BaseRepository.cs (with the interface defining the method)

public abstract class BaseRepository: IBaseRepository
{
    public IDbConnection OpenConnection()
    {
        IDbConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["myconnection"].ConnectionString);
        connection.Open();
        return connection;
    }

}

A Bootstraper.cs called from global.asax.cs with:

public static class Bootstrapper
    {
        public static void Initialise()
        {
            var container = BuildUnityContainer();

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }

        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();

            container.RegisterType<IBaseRepository, BaseRepository>();
            container.RegisterType<ISuppliersRepository, SuppliersRepository>();
            container.RegisterInstance<IHttpControllerActivator>(new HttpControllerActivator(container));
            container.RegisterControllers();


            return container;
        }
    }

And two controllers, first one resolves the repository fine:

public class VenueController : MasterController
    {
        [Dependency]
        public SuppliersRepository _SuppliersRepository { get; set; }
    }

But this one fails:

public class AjaxController : Controller
    {
        [Dependency]
        public BaseRepository _BaseRepository { get; set; }
}

It throws a System.InvalidOperationException: The type BaseRepository cannot be constructed. You must configure the container to supply this value.

Any idea what am I doing wrong?

Upvotes: 1

Views: 1509

Answers (2)

archil
archil

Reputation: 39491

First of all, when using dependency injection, it's better to have dependencies on interfaces, rather than having dependencies on concrete classes. I would change your controllers to

public class VenueController : MasterController
{
    [Dependency]
    public ISuppliersRepository _SuppliersRepository { get; set; }
}


public class AjaxController : Controller
{
    [Dependency]
    public IBaseRepository _BaseRepository { get; set; }
}

Second, BaseRepository is abstract class. Instances of abstract class can not be constructed, and I think that's the reason why it fails when unity comes to actually creating BaseRepository. You should inject concrete classes.

container.RegisterType<IBaseRepository, SomeConcreteImplementationOfBaseRepository>();

Upvotes: 2

RB.
RB.

Reputation: 37182

You should define your classes to take a property of IRepository, e.g:

public class AjaxController : Controller
{
        [Dependency]
        public IRepository _BaseRepository { get; set; }
}

Your properties should always be defined in terms of the interface, not the concrete implementation, otherwise you have tied yourself to the implementation, thus making the use of dependency injection rather pointless!

Upvotes: 0

Related Questions