1

I'm using structure map as my IOC with web api and I have an injected dependency in my controller and it's concrete type also has a dependecy.

Controller

[RoutePrefix("api/products")]
public class ProductsController : BaseApiController
{

    //private readonly ProductRepository _manageProducts;
    private readonly IProductFactory _productFactory;
    private readonly IGenericRepository _genericRepository;

    public ProductsController(IProductFactory productFactory, IGenericRepository genericRepository)
    {
        _productFactory = productFactory;
        _genericRepository = genericRepository;
        //_manageProducts = new ProductRepository();
    }

    [Authorize]
    [Route("addProduct")]
    public IHttpActionResult AddNewProduct(ProductViewModels.AddProductViewModel product)
    {
        if (User.IsInRole("Admin"))
        {

            _productFactory.CreateProduct(product);
            return Ok("Product Successfully Added");
        }
        return BadRequest("Your must have Administrator rights to perform the operation.");
    }
}

Factory

public class ProductFactory : IProductFactory
{
    private readonly IGenericRepository _genericRepository;

    public ProductFactory(IGenericRepository genericRepository)
    {
        _genericRepository = genericRepository;
    }


    /// <summary>
    /// Creates the product.
    /// </summary>
    /// <returns>The product.</returns>
    /// <param name="viewModel">New product.</param>
    public Product CreateProduct(ProductViewModels.AddProductViewModel viewModel)
    {
        var productToBeAdded = new Product
        {
            Title = viewModel.Title,
            ISBN = viewModel.ISBN,
        };
        return productToBeAdded;
    }
}

When I try to call product controller addproducts I get this runtime error for null reference exception:

{
  "Message": "An error has occurred.",
  "ExceptionMessage": "Object reference not set to an instance of an object.",
  "ExceptionType": "System.NullReferenceException",
  "StackTrace": "   at ICEBookshop.API.Factories.ProductFactory.CreateProduct(AddProductViewModel viewModel) in C:\\Users\\GOWDY_N\\Source\\Repos\\ICEBookshop.API\\ICEBookshop.API\\P00603ClientApi\\Factories\\ProductFactory.cs:line 29\r\n   at ICEBookshop.API.Controllers.ProductsController.AddNewProduct(AddProductViewModel product) in C:\\Users\\GOWDY_N\\Source\\Repos\\ICEBookshop.API\\ICEBookshop.API\\P00603ClientApi\\Controllers\\ProductsController.cs:line 95\r\n   at lambda_method(Closure , Object , Object[] )\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}

This is what I've done with structuremap

public class DefaultRegistry : Registry
{
    #region Constructors and Destructors

    public DefaultRegistry()
    {
        Scan(
            scan =>
            {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
            });
        For<IGenericRepository>().Use<GenericRepository<ApplicationDbContext>>();
        For<IProductFactory>()
            .Use<ProductFactory>()
            .Ctor<IGenericRepository>()
            .Is<GenericRepository<ApplicationDbContext>>().Named("DefaultInstanceKey");


        #endregion
    }
}

I thought this would fix it so it knows how to resolve my factory:

 For<IProductFactory>()
                    .Use<ProductFactory>()
                    .Ctor<IGenericRepository>()
                    .Is<GenericRepository<ApplicationDbContext>>().Named("DefaultInstanceKey");

But it doesn't work neither. Does anyone know how to fix this?

1 Answer 1

1

Just register the two interfaces and their implementations. The framework will resolve the dependencies when resolving the target.

For<IGenericRepository>().Use<GenericRepository<ApplicationDbContext>>();
For<IProductFactory>().Use<ProductFactory>();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.