5

I need help understanding Unity and how IOC works.

I have this in my UnityContainer

var container = new UnityContainer();

// Register types            
container.RegisterType<IService, Service>(new HierarchicalLifetimeManager());            

config.DependencyResolver = new UnityResolver(container);

Then in my Web API controller, I understand that IService is injected by Unity because it was a registered type.

public class MyController : ApiController
{
    private IService _service;

    //-------  Inject dependency - from Unity 'container.RegisterType'
    public MyController(IService service)
    {
        _service = service;
    }   

    [HttpGet]
    public IHttpActionResult Get(int id)
    {
        var test = _service.GetItemById(id);
        return Ok(test);
    }
}

My Service Interface

public interface IService
    {
        Item GetItemById(int id);
    }

My Service Implementation has its own constructor that takes an EntityFramework DBContext object. (EF6)

public class Service : IService
    {
        private MyDbContext db;

        // ---  how is this happening!?
        public IService(MyDbContext context)
        {
            // Who is calling this constructor and how is 'context' a newed instance of the DBContext?
            db = context;
        }

        public Item GetItemById(int id)
        {
            // How is this working and db isn't null?
            return db.Items.FirstOrDefault(x => x.EntityId == id);
        }
    }
1
  • Most probably MyDbContext has a parameterless constructor. Unity can resolve concrete classes without registration. Commented May 25, 2016 at 14:54

1 Answer 1

2

The reason it is working is that MyDbContext has a parameterless constructor (or it has a constructor that contains parameters that unity can resolve), and because unity by default can resolve concrete types without registration.

Quoting from this reference:

When you attempt to resolve a non-mapped concrete class that does not have a matching registration in the container, Unity will create an instance of that class and populate any dependencies.

You also need to understand the concept of auto-wiring.

When the container tries to resolve MyController, it detects that it needs to resolve IService which is mapped to Service. When the container tries to resolve Service, it detects that it needs to resolve MyDbContext. This process is called auto-wiring and is done recursively until the whole object graph is created.

Sign up to request clarification or add additional context in comments.

2 Comments

That is some crazy black magic there! This was a very clear explanation. Thank you.

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.