Search code examples
c#inversion-of-controlsimple-injectorservice-layer

Parameter not registered when using Simple Injector to inject into an web api Controller Constructor


currently getting the following error

The constructor of type ChurchController contains the parameter with name 'churchService' and type IChurchService that is not registered. Please ensure IChurchService is registered, or change the constructor of ChurchController.

im using Simple Injector but im new to IOC not sure what the error message means or what ive done wrong ive included my code below

SimpleInjectorWebApiInitializer.cs

 public static class SimpleInjectorWebApiInitializer
    {
        public static void Initialize()
        {
            var container = new Container();
            container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

            InitializeContainer(container);

            container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

            container.Verify();

            GlobalConfiguration.Configuration.DependencyResolver =
                new SimpleInjectorWebApiDependencyResolver(container);
        }

        private static void InitializeContainer(Container container)
        {
            // For instance:
            container.Register(typeof(IRepository<>), typeof(EFRepository<>));


        }

    }
 public interface IRepository<T> where T : class
    {
        //To query using LINQ
        IQueryable<T> GetAll();

        //Returning Movie or Review by id
        T GetById(int id);

        //Adding Movie or Review
        void Add(T entity);

        //Updating Movie or Review
        void Update(T entity);

        //Deleting Moovie or Review
        void Delete(T entity);

        //Deleting Movie or Review by id
        void Delete(int id);

    }

public class EFRepository<T> : IRepository<T> where T : class
{
    public EFRepository(DbContext dbContext)
    {
        if (dbContext == null)
            throw new ArgumentNullException("dbContext");
        DbContext = dbContext;
        DbSet = DbContext.Set<T>();
    }

    protected DbContext DbContext { get; set; }
    protected DbSet<T> DbSet { get; set; }
    public virtual IQueryable<T> GetAll()
    {
        return DbSet;
    }

    public virtual T GetById(int id)
    {
        return DbSet.Find(id);
    }

    public virtual void Add(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Detached)
        {
            dbEntityEntry.State = EntityState.Added;
        }
        else
        {
            DbSet.Add(entity);
        }
    }

    public virtual void Update(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Detached)
        {
            DbSet.Attach(entity);
        }
        dbEntityEntry.State = EntityState.Modified;
    }

    public void Delete(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Deleted)
        {
            dbEntityEntry.State = EntityState.Deleted;
        }
        else
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
        }
    }

    public void Delete(int id)
    {
        var entity = GetById(id);
        if (entity == null) return;

        Delete(entity);
    }
}

my model

   public class Church
    {
        public int Id { get; set; }
        public string ChurchName { get; set; }
        public virtual ICollection<User> Users { get; set; }

    }

set my controller to call my service

public class ChurchController : ApiController
{
    private readonly IChurchService _churchService;
    public ChurchController(IChurchService churchService)
    {

        _churchService = churchService;
    }

    public IEnumerable<Church> Get()
    {

        var result = _churchService.GetAll();

        return result;

    }
}

Solution

  • I never used Simple Injector before, but the IoC patterns is always the same. So as Steven says, you should register IChurchService in the container, so the Framework knows whats the Instance type to inject when demanded.

    private static void InitializeContainer(Container container)
    {
        // For instance:
        container.Register(typeof(IRepository<>), typeof(EFRepository<>));
        //Adding this should resolve it
        container.Register(typeof(IChurchService), typeof(ChurchService));
    }
    

    If ChurchService has any dependencies make sure to register those as well. Register all dependencies needed to complete the object graph