0
votes

Question background:

I am using unity to resolve a class and all its dependencies.

The issue:

I want to pass into the constructor of the classes an interface type through Unity, I'm attempting to achieve this as follows:

public static IFacade UnityNewsFacadeResolver()
   {
           IUnityContainer unityContainer = new UnityContainer();
           unityContainer.RegisterType<IFacade, NewsFacade>();
           IFacade newsFacadeInstance = unityContainer.Resolve<NewsFacade>();

           return newsFacadeInstance;
   }

The following shows the 'NewsFacade' class that Unity sets the constructor parameter. Note it is passing in a 'NewsStoryHandler' concrete type, I want to pass in the interface this class is based on i.e INewsStoryHandler:

private INewsStoryHandler _NewsStoryHandler;

    //*****Unity will only pass in a concrete implementation, I want to pass it as an interface but cannot:******
    public NewsFacade(NewsStoryHandler newsStoryHandler)
    {
        if (newsStoryHandler == null)
        {
            throw new Exception("newsStoryHandler is null at the constrcutor");
        }

        _NewsStoryHandler = newsStoryHandler;
    }

Currently Unity will not resolve and pass in an Interface type, it has to be a concrete implementation as shown above. This means I cannot Mock the interface when I unit test.

Can someone tell me why Unity will not resolve and pass in a type based on its interface?

1

1 Answers

2
votes

Unity is perfectly capable of resolving and providing a type based upon its interface.

To do so you must ensure that unity knows what concrete implementation to provide, i.e.

// Instruct unity to inject a NewsStoryHandler everywhere an INewsStoryHandler is specified
unityContainer.RegisterType<INewsStoryHandler, NewsStoryHandler>();
var newsFacadeInstance = unityContainer.Resolve<NewsFacade>();

This works assuming you have changed your NewsFacade constructor to have a parameter of type INewsStoryHandler.

When it comes to unit testing, you are then able to mock the INewsStoryHandler to make testing of your NewsFacade simpler, an example using Moq:

// Setup and configure the mock
var mockNewsStoryHandler = new Mock<INewsStoryHandler>();
mockNewsStoryHandler.Setup(h => h.GetAllStories()).Returns(Enumerable.Empty<NewsStory>());

// Inject the mock
var newsFacade = new NewsFacade(mockNewsStoryHandler.Object);
newsFacade.DoSomethingWithAllStories();

// Verify GetAllStories() was called exactly once
mockNewsStoryHandler.Verify(h => h.GetAllStories(), Times.Once);