Hansel
Hansel

Reputation: 1958

C# - IoC - Autofac Dependency Injection on WebAPI 2

I am having some trouble configuring Autofac with my application. I would appreciate all of your help. Below is the code with the exception. Should you need more details please don't hesitate to comment. Thanks!

  1. Api Config

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        var setings = config.Formatters.JsonFormatter.SerializerSettings;
        setings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        setings.Formatting = Formatting.Indented;
    
        // Web API Cors
        var origin = "https://localhost:44381";
        EnableCorsAttribute cors = new EnableCorsAttribute(origin, "*", "*");
        config.EnableCors(cors);
    
        // DI
        var builder = new ContainerBuilder();
    
        builder.RegisterType<AlertRepository>()
            .As<IAlertRepository>();
        builder.RegisterType<UnitOfWork>()
            .As<IUnitOfWork>();
        builder.RegisterGeneric(typeof(Repository<>))
            .As(typeof(IRepository<>))
            .InstancePerRequest();
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    
        var container = builder.Build();
        GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    
        // Web API routes
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
    
  2. Unit of Work Class

    public class UnitOfWork : IUnitOfWork
    {
            private readonly CRNetContext _context;
    
            public UnitOfWork(CRNetContext context)
            {
                _context = context;
                Alerts = new AlertRepository(_context);
            }
    
            public IAlertRepository Alerts { get; private set; }
    
            public int Complete()
            {
                return _context.SaveChanges();
            }
    
            public void Dispose()
            {
                _context.Dispose();
            }
    }
    
  3. Exception

{ "message": "An error has occurred.", "exceptionMessage": "An error occurred when trying to create a controller of type 'AlertsController'. Make sure that the controller has a parameterless public constructor.", "exceptionType": "System.InvalidOperationException", "stackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__15.MoveNext()", "innerException": { "message": "An error has occurred.", "exceptionMessage": "An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = AlertsController (ReflectionActivator), Services = [CRNET.API.Controllers.AlertsController], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = UnitOfWork (ReflectionActivator), Services = [CRNET.DAL.Persistance.IUnitOfWork], Lifetime = Autofac.Core.Lifetime.MatchingScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'CRNET.DAL.Persistance.UnitOfWork' can be invoked with the available services and parameters:\r\nCannot resolve parameter 'CRNET.DAL.Models.CRNetContext context' of constructor 'Void .ctor(CRNET.DAL.Models.CRNetContext)'. (See inner exception for details.) (See inner exception for details.)", "exceptionType": "Autofac.Core.DependencyResolutionException", "stackTrace": " at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.Execute()\r\n at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable1 parameters, Object& instance)\r\n at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable1 parameters)\r\n at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)\r\n at Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type serviceType) in C:\projects\autofac-webapi\src\Autofac.Integration.WebApi\AutofacWebApiDependencyScope.cs:line 76\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)", "innerException": { "message": "An error has occurred.", "exceptionMessage": "An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = UnitOfWork (ReflectionActivator), Services = [CRNET.DAL.Persistance.IUnitOfWork], Lifetime = Autofac.Core.Lifetime.MatchingScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'CRNET.DAL.Persistance.UnitOfWork' can be invoked with the available services and parameters:\r\nCannot resolve parameter 'CRNET.DAL.Models.CRNetContext context' of constructor 'Void .ctor(CRNET.DAL.Models.CRNetContext)'. (See inner exception for details.)", "exceptionType": "Autofac.Core.DependencyResolutionException", "stackTrace": " at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.b__5_0()\r\n at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func1 creator)\r\n at Autofac.Core.Resolving.InstanceLookup.Execute()\r\n at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.Core.Activators.Reflection.AutowiringParameter.<>c__DisplayClass0_0.<CanSupplyValue>b__0()\r\n at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()\r\n at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters)", "innerException": { "message": "An error has occurred.", "exceptionMessage": "None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'CRNET.DAL.Persistance.UnitOfWork' can be invoked with the available services and parameters:\r\nCannot resolve parameter 'CRNET.DAL.Models.CRNetContext context' of constructor 'Void .ctor(CRNET.DAL.Models.CRNetContext)'.", "exceptionType": "Autofac.Core.DependencyResolutionException", "stackTrace": " at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext context, IEnumerable1 parameters)\r\n at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters)" } } } }

Upvotes: 3

Views: 2806

Answers (1)

Igor
Igor

Reputation: 62298

Cannot resolve parameter 'CRNET.DAL.Models.CRNetContext context'...

You never register the type CRNetContext with Autofac. To fix it add:

builder.RegisterType<CRNET.DAL.Models.CRNetContext>().AsSelf();

Upvotes: 2

Related Questions