Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection doesn't know about type that I want to inject

I want to use HaveBox for Dependency Injection. But it isn't question about HaveBox. So I created base controller:

public abstract class BaseController : Controller
    {
        protected  readonly IRepository m_Repository;

        protected BaseController(IRepository repository)
        {
            m_Repository = repository;
        }
    }

And my HomeController was inherited from BaseController. Add HaveBoxConfig.RegisterTypes(); to Application_Start method and implementation of HaveBoxConfig is:

 public class HaveBoxConfig
    {
        public static void RegisterTypes()
        {
            var container = new Container();
            container.Configure(config => config.For<IService>().Use<Service>());
            container.Configure(config => config.For<IRepository>().Use<Repository>());
            IDependencyResolver resolver = DependencyResolver.Current;
            var newResolver = new MyResolver(container, resolver);
            DependencyResolver.SetResolver(newResolver);
        }
    }

And my resolver:

public class MyResolver : IDependencyResolver
    {
        private readonly IContainer m_container;
        private readonly IDependencyResolver m_resolver;
        public MyResolver(IContainer container, IDependencyResolver resolver)
        {
            m_container = container;
            m_resolver = resolver;
        }
        public object GetService(Type serviceType)
        {
            try
            {
                return m_container.GetInstance(serviceType);
            }
            catch (Exception ex)
            {
                return m_resolver.GetService(serviceType);
            }
        }
        public IEnumerable<object> GetServices(Type serviceType)
        {
            return m_resolver.GetServices(serviceType);
        }
    }

Method GetService called for next types: IControllerFactory, IControllerActivator, HomeController but not for my IRepository.

What am I doing wrong? Why DI isn't executed for IRepository?

like image 277
RredCat Avatar asked Dec 13 '13 22:12

RredCat


People also ask

What is the problem with dependency injection?

The intent behind dependency injection is to achieve separation of concerns of construction and use of objects. If class A needs to use class B, it does not need to create an instance of it. This will give A too much responsibility since beside its actual requirements it has to manage the lifetime of the instance of B.

What is considered as a type of dependency injection?

There are three types of dependency injection — constructor injection, method injection, and property injection.

How do you inject dependency injection?

The injector class injects dependencies broadly in three ways: through a constructor, through a property, or through a method. Constructor Injection: In the constructor injection, the injector supplies the service (dependency) through the client class constructor.

Is dependency injection an overkill?

Of course. If you have a really small project with 12 classes, then a DI framework is almost certainly overkill.


2 Answers

You also need to implement a controller factory. Easiest way is to subclass DefaultControllerFactory. You can check how they do it with Castle Windsor. Then you tell ASP.NET MVC to use your implementation.

DependencyResolver.SetResolver(newResolver);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
like image 70
Ufuk Hacıoğulları Avatar answered Sep 19 '22 17:09

Ufuk Hacıoğulları


I have checked different ways to solve it. Most simple is just add my controllers to container. For example:

container.Configure(config => config.For<HomeController>().Use<HomeController>());

It is simple and clear. If you have complex project and for more graceful solution you can do it via reflection for all classes that implemented IController interface.

like image 33
RredCat Avatar answered Sep 19 '22 17:09

RredCat