1

I'm trying to implement a demo application to understand Unity and IoC. But I'm kind of struck.

I'm having error:

An error occurred when trying to create a controller of type 'ProductController'. Make sure that the controller has a parameterless public constructor.

Here is the brief overview of what I'm doing:

I have five projects:

  1. Data Model
  2. Business Services
  3. WebApi
  4. Business Entities
  5. Resolver

I'm following this code project tutorial: https://www.codeproject.com/articles/997216/restful-day-sharp-resolve-dependency-of-dependenci

I've completed Day 3. but I'm not able to resolve the issue.

Here is my WebApi Project Unity RegisterTypes function.

public static void RegisterTypes(IUnityContainer container)
{
    // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
    // container.LoadConfiguration();

    // TODO: Register your types here
    //container.RegisterType<IProductServices, ProductServices>();

    //Component initialization via MEF
    ComponentLoader.LoadContainer(container, ".\\bin", "WebApi.dll");
    ComponentLoader.LoadContainer(container, ".\\bin", "BusinessServices.dll");
}

Here is ProductController Constructor

public class ProductController : ApiController
{
    private readonly IProductServices _productServices;

    #region Public Constructor

    /// <summary>
    /// Public constructor to initialize product service instance
    /// </summary>
    public ProductController(IProductServices productServices)
    {
        _productServices = productServices;
    }

    #endregion

BusinessServices project is registering the dependencies in a DependencyResolver class

using Resolver;
using System.ComponentModel.Composition;

namespace BusinessServices
{
    [Export(typeof(IComponent))]
    public class DependencyResolver : IComponent
    {
        public void SetUp(IRegisterComponent registerComponent)
        {
            registerComponent.RegisterType<IProductServices, ProductServices>();
        }
    }
}

Can anybody help me?

Thanks!

Saadi
  • 2,211
  • 4
  • 21
  • 50

1 Answers1

0

You need to register needed types:

        container.RegisterType<ProductController>();
        container.RegisterType<IProductServices, ProductServices>();

given that you've implemented IDependencyResolver.GetService using your Unity container, for example:

    public object GetService(Type serviceType)
    {
        if(container.IsRegistered(serviceType))
        {
            return container.Resolve(serviceType);
        }
        return null;
    }

a simple demo can be done like this:

public class UnityResolver : IDependencyResolver
{
    public IUnityContainer _container;

    public UnityResolver()
    {
        _container = new UnityContainer();
        RegisterTypes(_container);
    }

    public IDependencyScope BeginScope()
    {
        return this;
    }

    public object GetService(Type serviceType)
    {
        if(_container.IsRegistered(serviceType))
        {
            return _container.Resolve(serviceType);
        }
        return null;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return Enumerable.Empty<object>();
    }

    public void Dispose()
    {
    }

    public static void RegisterTypes(IUnityContainer container)
    {
        // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
        // container.LoadConfiguration();

        // TODO: Register your types here
        container.RegisterType<ProductController>();
        container.RegisterType<IProductServices, ProductServices>();

        //Component initialization via MEF
        //ComponentLoader.LoadContainer(container, ".\\bin", "WebApi.dll");
        //ComponentLoader.LoadContainer(container, ".\\bin", "BusinessServices.dll");
    }
}

and set the resolver in Application_Start:

GlobalConfiguration.DependencyResolver = new UnityResolver();
Bob Dust
  • 2,370
  • 1
  • 17
  • 13
  • 1
    Thank you for your answer but I want to ask why do I need to register my ProductController? – Saadi Dec 15 '16 at 07:44
  • `ProductController` needs registering so that the web api resolver will use the instance resolved by Unity container rather than calling the default constructor. – Bob Dust Dec 15 '16 at 07:50
  • No, it's not working. I even try to register the `ProductController` – Saadi Dec 15 '16 at 07:52
  • @Saadi, I'm assuming you're customizing web api dependency resolver. Have you set it in `Application_Start`, for example, like this: `GlobalConfiguration.DependencyResolver = new UnityResolver();` in which `UnityResolver` implements `IDependencyResolver`? – Bob Dust Dec 15 '16 at 07:56
  • Yes, I have called the`UnityWebActivator.Start();` function in `Application_Start` – Saadi Dec 15 '16 at 07:58
  • 1
    Don't get stuck with the complicated article. Try something simple first, @Saadi. Answer updated. – Bob Dust Dec 15 '16 at 08:06