I am using Unity to do my DI and I have encountered the following error:-
"An error occurred when trying to create a controller of type 'UploadController'. Make sure that the controller has a parameterless public constructor."
I have the following UnityResolver:-
public class UnityResolver : IDependencyResolver, IDependencyScope, System.Web.Http.Dependencies.IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
}
I have created a UnityConfig as follows:-
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
BuildUnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// you don't need to register controllers
container.RegisterType<IFileHelpers, FileHelpers>();
container.RegisterType<IDatabaseHelper, DatabaseHelper>();
container.RegisterType<IPlayersHelpers, PlayersHelpers>();
container.RegisterType<IBaseRepository, BaseRepository>();
container.RegisterType<IAttribsRepository, AttribsRepository>();
container.RegisterType<IPlayerRepository, PlayerRepository>();
container.RegisterType<IFileRepository, FileRepository>();
container.RegisterType<IPlayerAttribsRepository, PlayerAttribsRepository>();
container.RegisterType<FMContext>();
container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());
return container;
}
}
}
Im initializing everyting in the WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API configuration and services
var container = new UnityContainer();
UnityConfig.RegisterComponents();
config.DependencyResolver = new UnityResolver(container);
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
And this is my UploadController class:-
public class UploadController : ApiController
{
private readonly IFileHelpers _fileHelpers;
private readonly IDatabaseHelper _databaseHelper;
private readonly IPlayersHelpers _playersHelpers;
public UploadController(IFileHelpers fileHelpers, IDatabaseHelper databaseHelper, IPlayersHelpers playersHelpers)
{
_fileHelpers = fileHelpers;
_databaseHelper = databaseHelper;
_playersHelpers = playersHelpers;
}
public async Task<HttpResponseMessage> Post()
{........................}
Can you please help me in determining what am I doing wrong. Do I need to declare something else for this to work?
Thanks for your help and time
In your Register method, you have the following code:
// ...
// Web API configuration and services
var container = new UnityContainer();
UnityConfig.RegisterComponents();
config.DependencyResolver = new UnityResolver(container);
However, there is nothing registered to that container. There is a separate container (with registrations) being created in your static UnityConfig class, but that container is not being passed to the UnityResolver object...
Related
I have been following this article:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection#dependency-scope-and-controller-lifetime
The error I get is in the title:
Make sure that the controller has a parameterless public constructor.
Basically the Unity code is the same as in the project from microsoft.
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var container = new UnityContainer();
container.RegisterType<ITrace, Trace>(new HierarchicalLifetimeManager());
container.RegisterType<IUtility, Utility>(new HierarchicalLifetimeManager());
container.RegisterType<IValidator, Validator>(new HierarchicalLifetimeManager());
container.RegisterType<IDeliveryService, DeliveryService>(new HierarchicalLifetimeManager());
container.RegisterType<ISaleService, SaleService>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
I have UnityResolver:
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
Unity should instantiate the controllers using this. My only concern is the db context. I tried searching for ways to register but I got nothing.
As asked here is my dbcontext:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false)
{
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
Configuration.ValidateOnSaveEnabled = false;
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
I am using Unity for the first time.
In Unity sometimes custom classes that have a specific constructor also require an additional parameter-less constructor (It may be doing nothing but has to exist) like
public UnityResolver(){ }
Afaik this is mostly related to (de)serialization. Not sure why it is required in our specific case .. but that is what the error tries to tell you ;)
Earlier in WebAPI, I used to implement Unity container Dependency Injection as below
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//I want to implement below in Azure Function V2
var container = new UnityContainer();
container.RegisterType<IDeviceRepository, DeviceRepository>(new HierarchicalLifetimeManager());
container.RegisterType<IFilterRepository, FilterRepository>(new HierarchicalLifetimeManager());
container.RegisterType<INEORepository, NEORepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
}
}
How can I implement above code in Azure Function V2.
I had gone through few online articles but didn't get proper solution.
Kindly suggest.
I have used below code to implement DI in Azure functions.
public class GenericDependencyInjection
{
private static readonly UnityContainer UnityContainer = new UnityContainer();
public GenericDependencyInjection()
{
try
{
UnityContainer.RegisterType<IOperations,Operations>(new ContainerControlledLifetimeManager());
}
catch (Exception ex)
{
throw ;
}
}
public T Retrieve<T>()
{
return UnityContainer.Resolve<T>();
}
}
I have called Retrieve method by passing generic type as below in other classes
var data = new GenericDependencyInjection().Retrieve<EmpDetails>();
return await data.UpdateDetails(EmpId, Name); //calling class EmpDetails method
I have a Web Api app that consumes another REST Api client. I wrapped the REST API client into a service.
myproj/services/PostDataService.cs
public interface IPostDataService
{
Task<IList<Post>> GetAllPosts();
}
public class PostDataService : IPostDataService
{
private static IDataAPI NewDataAPIClient()
{
var client = new DataAPI(new Uri(ConfigurationManager.AppSettings["dataapi.url"]));
return client;
}
public async Task<IList<Post>> GetAllPosts()
{
using (var client = NewDataAPIClient())
{
var result = await client.Post.GetAllWithOperationResponseAsync();
return (IList<Post>) result.Response.Content;
}
}
}
....
I am using AutoFac and injecting the service in the controller
myproj/controllers/PostController.cs
public class PostController : ApiController
{
private readonly IPostDataService _postDataService;
public PostController(IPostDataService postDataService)
{
_postDataService = postDataService;
}
public async Task<IEnumerable<Post>> Get()
{
return await _postDataService.GetAllPosts();
}
}
But I am getting this error.
An error occurred when trying to create a controller of type
'PostController'. Make sure that the controller has a parameterless
public constructor.
Here is my Global.asax.cs
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ContainerConfig.Configure();
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
public static class ContainerConfig
{
private static IContainer _container;
public static IContainer GetContainer()
{
if (_container != null)
return _container;
var builder = new ContainerBuilder();
builder.RegisterType<PostDataService>()
.AsSelf()
.InstancePerLifetimeScope()
.AsImplementedInterfaces();
_container = builder.Build();
return _container;
}
public static IContainer Configure()
{
var container = GetContainer();
var webApiResolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;
return container;
}
Can someone spot what I am missing here?
Thanks
I'm missing
builder.RegisterApiControllers(typeof(PostController).Assembly).
Apparently, the controller also needs to be registered.
I use in my project Owin and Katana for OAuth authorization. And all work good but in global.asax.cs file I have some code for IOC container:
Bootstrapper.IncludingOnly.Assembly(Assembly.Load("Dashboard.Rest")).With.SimpleInjector().With.ServiceLocator().Start();
Container container = Bootstrapper.Container as Container;
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
I added this code in Startup.cs file but after it I catch next exception:
An exception of type
'Bootstrap.Extensions.Containers.NoContainerException' occurred in
Bootstrapper.dll but was not handled in user code
Additional information: Unable to continue. The container has not been
initialized.
and if I call someone api methods I catch next exception:
Unable to continue. The container has not been initialized.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details:
Bootstrap.Extensions.Containers.NoContainerException: Unable to
continue. The container has not been initialized.
Source Error:
Line 21: public Startup() Line 22: { Line 23:
Bootstrapper.IncludingOnly.Assembly(Assembly.Load("Dashboard.Rest")).With.SimpleInjector().With.ServiceLocator().Start();
Line 24: Container container = Bootstrapper.Container as
Container; Line 25:
GlobalConfiguration.Configuration.DependencyResolver = new
SimpleInjectorWebApiDependencyResolver(container);
I don't know how to fix it. Help me please. Thanks.
UPDATE
I have some SimpleInjectorRegisterTypes class for connect my interfaces and services:
public class SimpleInjectorRegisterTypes : ISimpleInjectorRegistration
{
public void Register(Container container)
container.RegisterSingle<IApplication, ApplicationService>();
}
}
And I have service where I write logic for API.
And in my controllers I create constructor for call my method with help interfaces:
public class ApplicationController : ApiController
{
private readonly IApplication _application;
public ApplicationController(IApplication application)
{
_application = application;
}
[HttpGet]
public IHttpActionResult GetAllApps()
{
var apps = _application.GetAllApps();
return apps == null ? (IHttpActionResult)Ok(new Application()) : Ok(apps);
}
....
I fix this problems. I just use other IOC container Unity
Here is an implementation of IDependencyResolver that wraps a Unity container.
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
container.RegisterType<IProductRepository, ProductRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
// Other Web API configuration not shown.
}
Some controllers with use IoC containers:
public class ProductsController : ApiController
{
private IProductRepository _repository;
public ProductsController(IProductRepository repository)
{
_repository = repository;
}
// Other controller methods not shown.
}
Dependency Injection in ASP.NET Web API 2
I'm receiving this odd error when trying to run my controller action in WebAPI:
An error occurred when trying to create a controller of type 'PostController'. Make sure that the controller has a parameterless public constructor.
Resolution of the dependency failed, type = "Example.Controllers.PostController", name = "(none)".
Exception occurred while: Calling constructor Example.Models.PostRepository().
Exception is: NullReferenceException - Object reference not set to an instance of an object.
Here's the problematic code:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
container.RegisterType<IPostRepository, PostRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ExampleApi",
routeTemplate: "api/{controller}"
);
}
}
public class PostController : ApiController
{
IPostRepository _repository;
public PostController(IPostRepository repository)
{
_repository = repository;
}
public IEnumerable<Post> GetAllProducts()
{
return _repository.GetAll();
}
}
public class PostRepository : IPostRepository
{
private IDbConnection _connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
public IEnumerable<Post> GetAll()
{
return _connection.Query<Post>("SELECT * FROM Posts").ToList();
}
}
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer Container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.Container = container;
}
public object GetService(Type serviceType)
{
if (!Container.IsRegistered(serviceType))
{
if (serviceType.IsAbstract || serviceType.IsInterface)
{
return null;
}
}
return Container.Resolve(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return Container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = Container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
Container.Dispose();
}
}
Does anyone have any idea of what might be the cause? I followed this tutorial: http://www.asp.net/web-api/overview/advanced/dependency-injection
In my experience when I see this message its normally some dependency is not able to be constructed or is missing a dependency. You have IPostRepository registered to PostRepository so that looks good. What about the SqlConnection created in PostRepository? Could you run some test code against just the repository to see if it constructs OK on its own?
Also just in browsing through your code is the check for interfaces blocking your resolution of the IPostRepository in the UnityResolver class?
if (serviceType.IsAbstract || serviceType.IsInterface)
{
return null;
}
The following link has a working project which is based on the same tutorial that you mentioned.
Not much difference to your code except the database will be targeting localdb, and on the UnityResolver there is no checks for Abstract class, which doesn't make any difference I think.
Now, you can use the project as a startup point to add your logic, and know exactly when it fails and why.
hope this helps.