Search code examples
c#genericsautofac

Autofac register generic repository where T is not class


I came across a problem when trying to resolve my generic repositories for database access. When I use these two as repoitory implementation/interface I am not able to resolve e.g. a IRepository<ICustomer>:

Interface:

public interface IRepository<T> where T : IDbModel
{ ... }

Implementation:

public class Repository<T> : IRepository<T> where T : DbModel
{ ... }

But when I replace IDbModel and DbModel with class in both cases it works as expected.

My registration looks like this:

builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
builder.RegisterType<DbModel>().As<IDbModel>();
builder.RegisterType<Customer>().As<ICustomer>();

For the sake of completeness, here are the ICustomer:

public interface ICustomer : IDbModel
{ ... }

The Customer:

public class Customer : DbModel, ICustomer
{ ... }

The IDbModel:

public interface IDbModel
{ ... }

And the DbModel (I checked if it works when I remove abstract but it doesn't):

public abstract class DbModel : IDbModel
{ ... }

I was wondering if it is possible to make my first attempt working in some way?


Solution

  • By asking Autofac to resolve IRepository<ICustomer> it will try to resolve Repository<ICustomer> and ICustomer is not a DbModel

    To fix the error you should replace the class type constraint on IRepository<TModel> to an interface type constraint.

     public class Repository<T> : IRepository<T> 
        where T : IDbModel 
     { }