Autofac and ASP .Net MVC 4 Web API
asp.net-mvc-4, asp.net-web-api, autofac, sharepoint-2013
Solution
You have registered your `IRepository` wrong. With the line:
builder.RegisterType<SharePointRepository<IEntity>>().As<IRepository<IEntity>>();
You told Autofac that whenever somebody will request an `IRepository<IEntity>` give them a `SharePointRepository<IEntity>`, but you are requesting a concrete `IRepository<Integration>` so you get an exception.
What you need is the open generic registration feature of Autofac. So change your registration to:
builder.RegisterGeneric(typeof(SharePointRepository<>))
.As(typeof(IRepository<>));
It will work as you would expect you when you ask for a `IRepository<Integration>` it will give a `SharePointRepository<Integration>`.
You also have a second unrelated problem: your `SharePointRepository` has only an `internal` constructor.
Autofac by default only looks for `public` constructors so you either change your constructor and class to `public` or you need to tell to Autofac to look for NonPublic constructors with the `FindConstructorsWith` method:
builder
.RegisterType<SharePointRepository<IEntity>>()
.FindConstructorsWith(
new DefaultConstructorFinder(type =>
type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)))
.As<IRepository<IEntity>>();
Problem
I am using Autofac for IoC in my ASP .Net MVC 4 project. Autofac is having some trouble initializing the repository and passing it to the API Controller. I am sure I am missing something in my configuration. Here is the error I get when I navigate to: `https://localhost:44305/api/integration` ``` <Error> <Message>An error has occurred.</Message> <ExceptionMessage> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'EL.Web.Controllers.API.IntegrationController' can be invoked with the available services and parameters: Cannot resolve parameter 'EL.Web.Infrastructure.IRepository`1[EL.Web.Models.Integration] repository' of constructor 'Void .ctor(EL.Web.Infrastructure.IRepository`1[EL.Web.Models.Integration])'. </ExceptionMessage> <ExceptionType>Autofac.Core.DependencyResolutionException</ExceptionType> <StackTrace> at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) at Autofac.Core.Resolving.InstanceLookup.Execute() at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters) at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters) at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType) at Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type serviceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) </StackTrace> </Error> ``` Here are some relevant bits of code: IoC Bootstrapper: ``` public static class Bootstrapper { public static void Initialize() { var builder = new ContainerBuilder(); builder.RegisterControllers(Assembly.GetExecutingAssembly()); builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); builder.Register(x => new SharePointContext(HttpContext.Current.Request)).As<ISharePointContext>().SingleInstance(); builder.RegisterType<SharePointRepository<IEntity>>().As<IRepository<IEntity>>(); builder.RegisterType<SharePointContextFilter>().SingleInstance(); builder.RegisterFilterProvider(); IContainer container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); var resolver = new AutofacWebApiDependencyResolver(container); GlobalConfiguration.Configuration.DependencyResolver = resolver; } } ``` IRepository: ``` public interface IRepository<T> { void Add(T entity); void Delete(int id); IEnumerable<T> Find(Expression<Func<T, bool>> filter = null); void Update(int id, T entity); } ``` SharePointRepository: ``` internal class SharePointRepository<T> : IRepository<T> where T : IEntity { private readonly ISharePointContext _context; private readonly string _listName; internal SharePointRepository(ISharePointContext context) { _context = context; object[] attributes = typeof (T).GetCustomAttributes(typeof (SharePointListAttribute), false); if (!attributes.Any()) { throw new Exception("No associated SharePoint list defined for " + typeof (T)); } _listName = ((SharePointListAttribute) attributes[0]).ListName; } public void Add(T entity) { throw new NotImplementedException(); } public void Delete(int id) { throw new NotImplementedException(); } public IEnumerable<T> Find(Expression<Func<T, bool>> filter) { throw new NotImplementedException(); } public void Update(int id, T entity) { throw new NotImplementedException(); } } ``` IntegrationController: ``` public class IntegrationController : ApiController { private readonly IRepository<Integration> _repository; public IntegrationController(IRepository<Integration> repository) { _repository = repository; } public void Delete(Guid integrationId) { _repository.Delete(Get(integrationId).Id); } public IEnumerable<Integration> Get() { return _repository.Find(); } public Integration Get(Guid integrationId) { return _repository.Find(i => i.IntegrationId == integrationId).FirstOrDefault(); } public void Post([FromBody] Integration integration) { _repository.Add(integration); } public void Put(Guid integrationId, [FromBody] Integration integration) { _repository.Update(Get(integrationId).Id, integration); } } ``` IEntity: ``` internal interface IEntity { int Id { get; } } ``` Entity: ``` public abstract class Entity : IEntity { protected Entity(int id) { Id = id; } public int Id { get; private set; } } ``` Integration: ``` [SharePointList("Integrations")] public class Integration : Entity { public Integration(int id) : base(id) { } public string ApiUrl { get; set; } public bool DeletionAllowed { get; set; } public Guid IntegrationId { get; set; } public string Key { get; set; } public string List { get; set; } public bool OutgoingAllowed { get; set; } public string RemoteWeb { get; set; } public string Web { get; set; } } ```