Exception in Autofac : No parameterless constructor defined for this object - c#

Here is my class where dependencies are resolved
namespace TestProj
{
public static class Bootstrapper
{
public static void Run()
{
SetAutofacWebAPI();
}
private static void SetAutofacWebAPI()
{
var builder = new ContainerBuilder();
builder.RegisterType<UserService>().As<IUserService>().InstancePerRequest();
builder.RegisterType<Encryption>().As<IEncryption>().InstancePerRequest();
DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
}
}
}
In the Global.asax, I have this : Bootstrapper.Run();
Here is my UserService class:
public class UserService : IUserService
{
private readonly IEncryption _Encryption;
public UserService(Encryption Encryption)
{
_Encryption = Encryption;
}
//Rest of the service here
}
the Encryption class is a similar one.
And the controller is here :
public class UserController : Controller
{
private readonly IUserService _UserService;
public AccountController(UserService UserService)
{
_UserService = UserService;
}
public JsonResult GetLoginLogs(int Id)
{
var Logs = _UserService.GetLoginLogById(Id);
return Json(Logs, JsonRequestBehavior.AllowGet);
}
//The rest of the controller
}
here is the version info:
Autofac : 3.5.2
MVC : 4.0.40804.0
DOTNET : 4
And then, when try localhost:5000/Account/GetLoginLogs/1 this exception comes up:
No parameterless constructor defined for this object.
Someone please help. I am in seriously in trouble!

I think you are confusing how you registered the dependencies.
Update from comments by #Amy:
You also failed to register your MVC controllers
// You can register controllers all at once using assembly scanning...
builder.RegisterControllers(Assembly.GetExecutingAssembly());
Source: documentation
Also use the interfaces instead of the concrete classes when explicitly injecting into the dependent classes as that is what you registered with the container.
public class UserService : IUserService {
private readonly IEncryption _Encryption;
public UserService(IEncryption Encryption) {
_Encryption = Encryption;
}
//Rest of the service here
}
public class UserController : Controller {
private readonly IUserService _UserService;
public AccountController(IUserService UserService) {
_UserService = UserService;
}
public JsonResult GetLoginLogs(int Id) {
var Logs = _UserService.GetLoginLogById(Id);
return Json(Logs, JsonRequestBehavior.AllowGet);
}
//The rest of the controller
}

Actually, I believe the exception you get is not misleading if you get deeper into it and analyze the exception message and stack trace. You would find exactly which service could not be found and created by the container - in this case it would be UserService in AccountController (and later, Encryption in UserService as well). The exception with "no parameterless contructor found" simply says that in existing contructor with parameters there is one or more parameters which cannot be resolved by the container, and, because the parameterless constructor is missing, required type cannot be created.
It can also mean you forgot to register your controllers in the container, so the Autofac has no idea it should inject any dependecies into the controllers.
Going further - Autofac is very explicit with the registrations - you can only inject/resolve what you registered at the start up of the application.
If you simply use builder.RegisterType<UserService>() - without any As<> you can only inject UserService directly. But when you add .As<>: builder.RegisterType<UserService>().As<IUserService>(), you cannot inject UserService anymore, but IUserService. To keep the possibility to inject UserService you would have to use AsSelf(): builder.RegisterType<UserService>().As<IUserService>().AsSelf(). Then, you can inject both IUserService and UserService. Keep in mind Autofac registration API is fluent, you can amend as many As<> as you want.
In Dependecy Injection world we do not like tidly coupled components, so injecting concrete classes, instead of interfaces - like you did - is not recommended - you should use interfaces wherever it is possible. So your registrations are correct, but you should inject IUserService instead of UserService and IEncryption instead of Encryption in your components.
It would ease potential unit testing of these components, allowing you mocking up dependencies easily.
Also, you should register your controllers as well:
builder.RegisterControllers(Assembly.GetExecutingAssembly())‌​;

Related

Injecting Repository into ActionFilter

I am trying to inject a repository into an action filter, but getting the following error:
An unhandled exception occurred while processing the request.
InvalidOperationException: Unable to resolve service for type
'...ISqlRepository' while attempting to activate
'...MyActionFilterAttribute'.
I'm trying to follow Steve Smith's pattern from here. Everything works fine until I add the ISqlRepository reference to the constructor.
Here are the relevant code bits:
Startup.cs
services.AddScoped<MyActionFilterAttribute>();
MyActionFilterAttribute.cs (I realize that I'm implementing IResultFilter here. I'm just trying to stick as close to the example).
public class MyActionFilterAttribute: IResultFilter
{
private ILogger _logger;
private ISqlRepository _sql;
public MyActionFilterAttribute(ILoggerFactory loggerFactory, ISqlRepository sql)
{
_logger = loggerFactory.CreateLogger<LoaderActionFilterAttribute>();
_sql = sql;
}
MyController.cs
[Route("api/[controller]")]
[ServiceFilter(typeof(MyActionFilterAttribute))]
public class MyController: Controller
You'll need to register your repository as you usually would with ioC:
services.AddScoped<ISqlRepository,SqlRepository>();
Then you'll need to do property injection to the attribute.
Looks like this -
public class MyActionFilterAttribute: IResultFilter
{
public static Func<ISqlRepository> GetSqlRepo;
private ISqlRepository _sql;
public MyActionFilterAttribute()
{
_sql = GetSqlRepo();
}
}
In your startup, you'll have access to your service collection, so can do the following
MyActionFilterAttribute.GetSqlRepo = () => services.GetService<ISqlRepository>()
You need to add ISqlRepository to your services:
services.AddScoped<ISqlRepository,SqlRepository>();
The reason the sample project referenced did not have to do this is because ILoggerFactory is added via the framework.

How to do Caching and Dependency Injection outside of Controller in .NET Core MVC

I've used DI purely for tests within a controller and I'm oddly having a real hard time using it outside of a controller. I had a static caching class called caching engine, but apparently DI and static classes don't mix well, so I decided to make it non-static instead. However, I can't get this to work well and I'm not sure what the best approach is. I have a controller that I need to pass products and send them to the view. However, for speed improvements, I'd like to use memory caching, but I'm really confused on the best design here. I'd like to know the best way to do this.
1) How does instantiating a new class work with DI if you don't pass the dependencies?
2) Should I inject my memorycache and product repository into the controller and then pass them into the cachingengine constructor? That seems like a lot of unnecessary parameter passing, so I didn't like this.
3) Should I just instantiate a MemoryCache class in the caching engine and not worry about DI?
4) Should I just switch the CachingEngine back to a static class?
Thank you for your help and advice. It is much appreciated.
Here's the Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//Add Dependencies
services.AddTransient<IProductRepository, ProductRepository>();
//Extention method that sets up the shared objects used in MVC apps
services.AddMvc();
services.AddMemoryCache();
....
}
}
Here's the Controller
public class MainController : Controller
{
private CachingEngine engine;
public MainController()
{
//This isn't valid, missing parameters
engine = new CachingEngine();
}
public IActionResult Index()
{
var products = CachingEngine.GetProducts();
....
}
}
And here's the caching class:
public class CachingEngine
{
private readonly IMemoryCache memoryCache;
private IProductRepository prodRepo;
public CachingEngine(IMemoryCache memory, IProductRepository rep)
{
memoryCache = memoryCache;
prodRepo = rep;
}
public List<Product> GetProducts()
{
var cacheKey = "Products";
List<Product> prods;
if (memoryCache.TryGetValue(cacheKey, out prods))
{
return prods;
}
else
{
memoryCache.Set(cacheKey, prodRepo.Products);
return prods;
}
}
}
First off, to clarify, a static class cannot be instantiated so how could you inject instantiations into its constructor using a dependency injection framework. It is not that static classes do not work well with DI, they do not work at all and make no sense in the context of dependency injection.
Your Controller needs a CachingEngine, so you need to inject it, a simple rule of setting up DI in your software: do not use the new operator.
Anytime you use the new operator you are tightly coupling your code to a particular type and you have the exact problem that Dependency Inject is trying to solve.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//Add Dependencies
services.AddTransient<IProductRepository, ProductRepository>();
//configure DI for IMemoryCache and CachingEngine
services.AddTransient<IMemoryCache, MyMemoryCacheClass>();
services.AddTransient<MyICachingEngineInterface, CachingEngine>();
//Extention method that sets up the shared objects used in MVC apps
services.AddMvc();
services.AddMemoryCache();
....
}
}
public class MainController : Controller
{
private readonly MyICachingEngineInterface _cachingEngine;
public MainController(MyICachingEngineInterface cachingEngine)
{
_cachingEngine = cachingEngine;
}
public IActionResult Index()
{
var products = _cachingEngine.GetProducts();
....
}
}

Getting IServiceProvider as a Dependency to get Optional Dependencies in ASP.NET Core

Is it a bad practice to get IServiceProvider injected to a service class, as a means to get optional dependencies in ASP.NET Core 2.0? Does this break Explicit Dependency Principal?
I've a class which requires an Optional Service, EventBus. If the EventBus is registered, I want the service class to publish an event, if not simply ignore it.
public class SomeService {
private readonly IServiceProvider _serviceProvider;
public SomeService(IServiceProvider serviceProvider) {
_serviceProvider = serviceProvider;
}
public SomeAction() {
var eventBus = _serviceProvider.GetService(typeof(IEventBus)) as IEventBus;
if (eventBus != null) {
eventBus.publish("SomeAction Happened!");
}
}
}
I can't see how to create optional dependencies with the built in IoC Container of ASP.NET Core 2.0.
EDIT: Any suggestions how to implement optional dependencies in ASP.NET Core? Or any other strategy to get the same effect without the anti-pattern?
It would not be considered optional if it is required directly by the method in order for it to function correctly.
It should be explicitly injected as a dependency
public class SomeService {
private readonly IEventBus eventBus;
public SomeService(IEventBus eventBus) {
this.eventBus = eventBus;
}
public SomeAction() {
if (eventBus != null) {
eventBus.publish("SomeAction Happened!");
}
//...
}
}
otherwise consider passing it explicitly to the method as an optional dependency
public SomeAction(IEventBus eventBus = null) {
if (eventBus != null) {
eventBus.publish("SomeAction Happened!");
}
//...
}
The Explicit Dependencies Principle states:
Methods and classes should explicitly require (typically through method parameters or
constructor parameters) any collaborating objects they need in order
to function correctly.
emphasis mine
Injecting IServiceProvider is debated as an anti-pattern as it follows a service locator pattern.
There are some exceptions for example if the dependent class is being also used as a factory.
Injecting IServiceProvider is an implementation of the Service Locator anti-pattern. Prevent from doing this. Neither should dependencies be optional. This introduces complexity. Instead, use the Null Object pattern. Making the dependency required, simplifies the consumer and its test.
In other words, SomeService should look as follows:
public class SomeService {
private readonly IEventBus _bus;
public SomeService(IEventBus bus) {
_bus = bus ?? throw new ArgumentNullException(nameof(bus));
}
public SomeAction() {
eventBus.publish("SomeAction Happened!");
}
}
In your Composition Root you use a NullEventBus implementation in case no real implementation exists. This should be as easy as this:
public class NullEventBus : IEventBus
{
public void publish(string message) {
// do nothing.
}
}
Since this implementation does nothing, it can be injected into all consumers.

Unity container can't resolve my class

I am trying to implement Unity as an IoC container in a learning project I am working on. I have a layered application, UI->Service->Logic->DataAccess.
It's an MVC Application on the UI side.
In my controller, I have a constructor:
public HomeController()
{
_container = new UnityContainer();
_container.RegisterType<IUserService, UserService>();
_container.RegisterType<IUserLogic, UserLogic>();
}
I then attempt to use the IService in one of my methods:
var service = _container.Resolve<IUserService>();
ReplyDto reply = service.Login(model.Email, model.Password);
But then get this error:
Resolution of the dependency failed, type = "Services.IUserService",
name = "(none)".
I'm not sure why it's saying this. Do I maybe have an issue with MVC and the constructor? Breakpoint on the Resolve line shows that the _container does have the interface I am trying to resolve.
My UserService class has this in the constructor:
private IUserLogic _userlogic;
public UserService(IUserLogic logic)
{
_userlogic = logic;
}
The Logic layer class is defined like this:
public class UserLogic : IUserLogic
{
public ILog _logger;
public IData _data;
public UserLogic(IData data, ILog logger)
{
_data = data;
_logger = logger;
}
I am still in the process of propagating the IoC patter down through all layers.
And finally, the data access layer is defined as:
public class Data :IData
{
Log _logger = new Log();
MyEntities entities;
public Data()
{
entities = new MyEntities();
var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance;
}
My _container has reference to the IUserLogic interfaces and which concrete class to use.
UserLogic(IData data, ILog logger) - neither IData nor ILog shown as registered in container - so if code is exactly like you have in the post it is the reason why IUserLogic can't be resolved when unity tries to pass argument to UserService(IUserLogic) constructor.
Fix: register all dependencies (recursively)
To achieve that consider:
make sure types with no dependencies has constructors without arguments
register instances instead of types - if that works for your system
make constructors depend on concrete types (as all concrete types by default registered with Unity) - not testable choice...
provide parameters for all non-interface/non class arguments like int/string (How resolve a dependency with unity passing arguments in the constructor?)
You should register container in the Global.asax.cs
public class Global : HttpApplication
{
private void Application_Start(object sender, EventArgs e)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IUserService, UserService>();
container.RegisterType<IUserLogic, UserLogic>();
UnityDependencyResolver dependencyResolver = new UnityDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver;
DependencyResolver.SetResolver(dependencyResolver);
}
}

Unity IOC sometimes cant resolve dependency

I am having a weird problem using Unity as an IOC container and im out of ideas of what could cause it. I have a service dependency in my webapi controller but it randomly fails to resolve this dependency. Sometimes i have to start my application 3 or 4 times and then it suddenly works again.
The error I am getting is:
Resolution of the dependency failed, type = "Base.WebApi.Controllers.ApiUsersController", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The type IApiUserService does not have an accessible constructor. ----------------------------------------------- At the time of the exception, the container was: Resolving Base.WebApi.Controllers.ApiUsersController,(none) Resolving parameter "apiUserService" of constructor Base.WebApi.Controllers.ApiUsersController(Base.BLL.Services.User.IApiUserService apiUserService) Resolving Base.BLL.Services.User.IApiUserService,(none)
For initializing and registering my types in unity i use the following:
public static void RegisterTypes(IUnityContainer container)
{
var myAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.FullName.StartsWith("Base") && !a.FullName.StartsWith("Base.WebApi")).ToArray();
container.RegisterType(typeof(Startup));
container.RegisterTypes(
UnityHelpers.GetTypesWithCustomAttribute<UnityIoCSingletonLifetimedAttribute>(myAssemblies),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled,
null
).RegisterTypes(
UnityHelpers.GetTypesWithCustomAttribute<UnityIoCTransientLifetimedAttribute>(myAssemblies),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.Transient);
}
As you can see i am using singletone and transient named attributes to define the way my dependencies should be resolved.
My controller looks like this:
public class ApiUsersController : ODataController
{
private readonly IApiUserService _apiUserService;
public ApiUsersController(IApiUserService apiUserService)
{
_apiUserService = apiUserService;
}
public IQueryable<ApiUserEntity> Get()
{
return this._apiUserService.GetUsers();
}
}
as you can see it has a dependency on user service which looks like this:
[UnityIoCTransientLifetimed]
public class ApiUserService : BaseService, IApiUserService
{
private readonly IUserRepository _userRepository;
public ApiUserService(IUserRepository userRepository, IUnitOfWork uow) : base(uow)
{
_userRepository = userRepository;
}
}
The api user repository looks like this:
[UnityIoCTransientLifetimed]
public class UserRepository : GenericRepository<ApiUserEntity>, IUserRepository
{
public UserRepository(IUnitOfWork unitOfWork, IDomainContext context) : base(unitOfWork, context)
{
}
Extending the following GenericRepository:
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
protected readonly BaseContext Context;
public GenericRepository(IUnitOfWork unitOfWork, IBaseContext context)
{
// register this repository with the unit of work.
unitOfWork.Register(this);
Context = (BaseContext)context;
}
With my unit of work that looks like this:
[UnityIoCSingletonLifetimed]
public class UnitOfWork : IUnitOfWork
{
private readonly Dictionary<string, IRepository> _repositories;
// unit of work class is responsible for creating the repository and then dispossing it when no longer needed.
public UnitOfWork()
{
_repositories = new Dictionary<string, IRepository>();
}
}
However it sometimes works and sometimes it doesnt and i cant figure out why or where to look.
Finally solved it thanks to some suggestions. Looking at the documentation for
AppDomain.CurrentDomain.GetAssemblies()
it says the following:
Gets the assemblies that have been loaded into the execution context of this application domain.
Which basically means that it only loads the assemblies when they are actually needed.
The way i solved it was by using the more reliable GetReferencedAssemblies which loads all assemblies even if they are not being used.
var allAssemblies = new ReadOnlyCollection<Assembly>(
BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList());
Restarted tons of times and not one resolve crash :) Thanks everyone! For everyone looking for more information check out this SO answer: Difference between AppDomain.GetAssemblies and BuildManager.GetReferencedAssemblies

Categories