0

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.

omkar.ghaisas
  • 235
  • 5
  • 19
  • please show the exception details – qujck Jun 08 '16 at 21:45
  • Added the exception details above in original question. Hope that helps – omkar.ghaisas Jun 09 '16 at 05:45
  • See also [this question](http://stackoverflow.com/questions/6109646/how-do-i-use-the-decorator-pattern-with-unity-without-explicitly-specifying-ever) and I especially like the answer with [this article](http://www.beefycode.com/post/Decorator-Unity-Container-Extension.aspx). – TylerOhlsen Jul 09 '16 at 04:01

1 Answers1

0

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.

Community
  • 1
  • 1
smoksnes
  • 10,509
  • 4
  • 49
  • 74