Vahid Amiri
Vahid Amiri

Reputation: 11117

Instantiating a class with injected constructor in C#

I was wondering if it's possible to make an object of a class that has a constructor with an injection of another class.

The class i want to instantiate:

using ClearBlog.IRepository;
using ClearBlog.Models;

namespace ClearBlog.Areas.Admin.Classes
{
    public class AdminArticleTags
    {
        private readonly IGenericRepository<ArticleTag> _db = null;

        public AdminArticleTags(IGenericRepository<ArticleTag> db)
        {
            _db = db;
        }

        public int InsertNew(int article, int tag)
        {
            // do smt here
        }
    }
}

I want to use the InsertNew method of the above class in another class like this:

using System.Linq;
using System.Web.Mvc;
using ClearBlog.Models;
using ClearBlog.Helpers;
using ClearBlog.IRepository;
using ClearBlog.Areas.Admin.Classes;

namespace ClearBlog.Areas.Admin.Controllers
{
    public class Someclass : Controller
    {
        private readonly IGenericRepository<Tag> _db = null;

        public Someclass(IGenericRepository<Tag> db)
        {
            _db = db;
        }

        public ActionResult Index()
        {
            AdminArticleTags at = new AdminArticleTags();
            at.InsertNew(10, 15);
        }
     }
 }

That is not possible now because of the constructor expecting an IGenericRepository.

Is it even possible?

If it's not, then what way do you recommend? mind the fact that I need to use the IGenericRepository that is the interface used by Ninject to bind to an implementation.

edit:

what I'm trying to do is very simple. I just want to make an object of AdminArticleTags and access it's method inside Someclass. even if i make an parameterless constructor for AdminArticlesTags it gives errors because it not going to inject IGenericRepository for that object. (because of constructor)

How would i make an object of AdminArticlesTags and use its methods??

edit2:

this is where i do Ninject bindings:

using Ninject;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using ClearBlog.IRepository;
using ClearBlog.Repository;
using AutoMapper;

namespace ClearBlog.Infrastructure
{
    public class NinjectDependencyResolver : IDependencyResolver
    {
        private IKernel kernel;
        public NinjectDependencyResolver(IKernel kernelParam)
        {
            kernel = kernelParam;
            AddBindings();
        }
        public object GetService(Type serviceType)
        {
            return kernel.TryGet(serviceType);
        }
        public IEnumerable<object> GetServices(Type serviceType)
        {
            return kernel.GetAll(serviceType);
        }
        private void AddBindings()
        {
            kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>));
            kernel.Rebind<IMappingEngine>().ToMethod(context => Mapper.Engine);
        }
    }
}

Upvotes: 1

Views: 5616

Answers (2)

Yacoub Massad
Yacoub Massad

Reputation: 27861

Use Constructor Injection.

If you don't care about obtaining a new instance of AdminArticleTags every time, then simply inject a AdminArticleTags into the controller like this:

public class Someclass : Controller
{
    private readonly AdminArticleTags m_AdminArticleTags;

    public Someclass(AdminArticleTags aat)
    {
        m_AdminArticleTags = aat;
    }

    public ActionResult Index()
    {
       m_AdminArticleTags.InsertNew(15, 42);
    }
}

Since you are using Ninject, it would be able to create the controller and pass the correct dependency.

If you require a new instance everytime inside the Index action, then you need some kind of factory. You can use the Func class like this:

public class Someclass : Controller
{
    private readonly Func<AdminArticleTags> m_AdminArticleTagsFactory;

    public Someclass(Func<AdminArticleTags> factory)
    {
        m_AdminArticleTagsFactory = factory;
    }

    public ActionResult Index()
    {
       AdminArticleTags at = m_AdminArticleTagsFactory();
       at.InsertNew(15, 42);
    }
}

In this case, you would have to install the Ninject.Extensions.Factory nuget package. This will allow the support of resolving Func based factories. Take a look at this.

An alternative to Func based factories are factory interfaces. Take a look at this.

Upvotes: 3

Gur
Gur

Reputation: 111

  1. yes. you can inject code even when the class has a parameterized constructor. though, it depends on how and with what technique/framework you inject.

  2. what you are doing in the example is not injection. just a simple instanciation. in addition, your code will not compile because you did not define an empty or a default constructor.

maybe if you give more details about you are trying to achieve it will be easier to assist specifically.

Upvotes: 0

Related Questions