No parameterless constructor defined for this object

220 views
Skip to first unread message

Chandrasekar Kesavan

unread,
Nov 5, 2015, 6:04:33 AM11/5/15
to Autofac
I have a Asp.net MVC5 project with the following format. I'm following the Onion Architecture.

//Domain
MyProject.Domain.Entities(POCO's)
MyProject.Domain.Repository.Interfaces(Repository Interfaces)

//Infrastructure Layer(Class Library)
MyProject.Infrastructure.Data(Data access EF Code First/Repositories)
MyProject.Infrastructure.DependencyResolution(Autofac container registration)

//Application Services
MyProject.Services
MyProject.Service.Interfaces


//Asp.Net web project
MyProject.Web

Reference:

1. "Web" include the reference of "Service.Interface", "Domain.Entities", "Infrastructure.DependencyResolution"
2. "Services" include the reference of "Domain.Entities", "Domain.Repository.Interfaces", "Service.Interface"
3. "Service.Interface" include the reference of "Domain.Entities"
4. "Domain.Repository.Interfaces" include the reference of "Domain.Entities"
5. DependencyResolution include the reference of "Services","Services.Interface", "Domain.Repository.Interfaces", "Infrastructure.Data"
6. "Infrastructure.Data" include the reference of "DomainEntities", "Domain Repository.Interfaces".


In DependencyResolver class library contains the following code.

public class AutofacConfig
    {
        public static void SetAutofacContainer()
        {           
            var builder = new ContainerBuilder();
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
            builder.RegisterType<DbFactory>().As<IDbFactory>().InstancePerRequest();     
            // Repositories            builder.RegisterAssemblyTypes(typeof(CompanyRepository).Assembly)
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces().InstancePerRequest();
            // Services
            builder.RegisterAssemblyTypes(typeof(CompanySerivce).Assembly)
               .Where(t => t.Name.EndsWith("Service"))
               .AsImplementedInterfaces().InstancePerRequest();

            IContainer container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
    }


In Web project Global.asax contains the following code:

using MyProject.Infrastructure.DependencyResolution
 protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            AutofacConfig.SetAutofacContainer();
}


I'm getting this Error: "No parameterless constructor defined for this object."

Because, In UserController constructor need the instance of UserService:

 public class UserController : Controller
    {
        private IUserService _userService;
        public UserController(IUserService userService)
        {
            _userService = userService;
        }
        // GET: User
        public ActionResult Index()
        {
            var users = _userService.GetAllUsers();
            return View(users);
        }
    }

and in MyProject.Service, UserService class need the instance of UserReopsitory, UnitOfWork


 public class UserService : IUserService
    {
        private readonly IUserRepository _userRepository;
        private readonly IUnitOfWork _unitOfWork;
        public UserService(IUserRepository userRepository, IUnitOfWork unitOfWork)
        {
            _userRepository = userRepository;
            _unitOfWork = unitOfWork;
        }
}

Note: Repositories and dbcontext can't be directly referenced by the UI layer(Web), UI layer must go through an application service.

According to my understand Global.asax call the AutofacConfig class to register the components, so AutofacConfig is registering the components for the assembly MyProject.Infrastructure.DependencyResolution. So how can I register the components to my Web project without referencing the dataaccess dll(i.e MyProject.Infrastructure.Data) ?

Thanks,
Chandru

Travis Illig

unread,
Nov 5, 2015, 11:48:21 AM11/5/15
to Autofac
If you want things registered with Autofac but don't want to reference the assemblies, you'll have to do a combination of assembly scanning and reflection-based registration. You can also use configuration if you'd rather not do scanning.

If you choose to do scanning, you'll need to load assemblies using Assembly.Load and pass the loaded assemblies to the RegisterAssemblyTypes like you are already doing.

If you choose to do configuration, which will do the assembly loading for you, you can follow the documentation.
Reply all
Reply to author
Forward
0 new messages