0
votes

Given below are my different class declarations and how I am trying to setup unity container configuration to get a Interface to Concrete class implementation. The code currently throws either an stackoverflow exception or suggests that a interface cannot be constructed.

Please help me fix, either the class structure or the container configuration.

CodesController Class -

public class CodesController : ApiController
{
    private readonly IUnitOfWorkAsync unitOfWork;
    private readonly ICodeRepository repository;

    public CodesController(IUnitOfWorkAsync unitOfWork, ICodeRepository codeRepository)
    {
        if (unitOfWork == null)
        {
            throw new ArgumentNullException("unitOfWork");
        }

        this.unitOfWork = unitOfWork;
        this.repository = codeRepository;
    }

//Other class level methods here
}

CodeRepository class -

public class CodeRepository : ICodeRepository
{
    private readonly ICodeRepository codeRepository;

    public CodeRepository(ICodeRepository repository)
    {
        this.codeRepository = repository;
    }

    public virtual async Task<IEnumerable<Code>> GetCodeAsync(string codeKey)
    { //Some implementation here}
}

ICodeRepository Interface -

public interface ICodeRepository : IRepositoryAsync<Code>
{
    Task<IEnumerable<Code>> GetCodeAsync(string codeKey);
}

IRepositoryAsync Interface -

public interface IRepositoryAsync<TEntity> : IRepository<TEntity> where TEntity : class, IPersistenceHint
{
    Task<bool> DeleteAsync(params object[] keyValues);
    Task<bool> DeleteAsync(CancellationToken cancellationToken, params object[] keyValues);
    Task<TEntity> FindAsync(params object[] keyValues);
    Task<TEntity> FindAsync(CancellationToken cancellationToken, params object[] keyValues);
}

Unity Container Configuration-

container.RegisterType<IUnitOfWorkAsync, UnitOfWork>(
            "test",
            new TransientLifetimeManager(),
            new InjectionConstructor(container.Resolve<IDataContextAsync>("test")));

container.RegisterType<ICodeRepository, CodeRepository>();
container.RegisterType<CodesController, CodesController>();

With this given configuration and class structure, based on my experimentation with container config, I get following exception -

JSON
exceptionMessage=An error occurred when trying to create a controller of type 'CodesController'. Make sure that the controller has a parameterless public constructor.
exceptionType=System.InvalidOperationException
innerException
exceptionMessage=Type '<Namespace>.Api.Controllers.CodesController' does not have a default constructor
stackTrace= at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)

Please suggest, if anything is wrong here, so that I can fix the same. Already struggling many days on this.

1
please show the exception details - qujck
Added the exception details above in original question. Hope that helps - omkar.ghaisas
See also this question and I especially like the answer with this article. - TylerOhlsen

1 Answers

0
votes

You're injecting ICodeRepository to CodeRepository, which probably causes to stackoverflow exception, since it will keep generating ICodeRepositories. It will generate a recursive call. Somewhat like this one:

public class BaseFoo
{
    public BaseFoo(BaseFoo foo){ }
}

public class Foo : BaseFoo
{
    public Foo() : base(new Foo()) { }
}

And regarding the "does not have a default constructor"-exception, have you registered a DependencyResolver for Web API? See one of these questions for more detailed information how to do it:

Using Unity with Web Api 2 gives error does not have a default constructor

Unity.WebApi | Make sure that the controller has a parameterless public constructor

ASP.Net MVC 4 Web API controller dosn't work with Unity.WebApi

As a side note, you shouldn't have to register the CodesController in your unity registration.