2014-02-06 5 views
0

Вопрос фон:Невозможно решить интерфейс с Unity

Я использую единства для решения класса и всех его зависимостей.

Вопрос:

Я хочу передать в конструктор классов тип интерфейса через Unity, я пытаюсь добиться этого следующим образом:

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

      return newsFacadeInstance; 
    } 

Следующая показывает класс NewsFacade, который Unity устанавливает параметр конструктора. Обратите внимание, что проходит в конкретном типе «NewsStoryHandler», я хочу передать в интерфейсе этого класса на основе т.е. 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; 
    } 

В настоящее время Unity не рассосется и передать в типе интерфейса, он должен быть как показано выше. Это означает, что я не могу Mock интерфейс, когда я тестирую модуль.

Может кто-нибудь сказать мне, почему Unity не решит и не передаст тип, основанный на его интерфейсе?

ответ

1

Unity идеально подходит для решения и предоставления типа, основанного на его интерфейсе.

Для этого вы должны убедиться, что единство знает, что конкретная реализация для обеспечения, т.е.

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

Это работает если вы изменили свой NewsFacade конструктор, чтобы иметь параметр типа INewsStoryHandler.

Когда дело доходит до модульного тестирования, вы тогда в состоянии дразнить INewsStoryHandler сделать тестирование вашей NewsFacade простой, пример использования 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); 
+0

Отличный ответ. Это заставило все это работать. Если я могу задать другой вопрос. У меня есть класс класса «верхний уровень», если «Фасад», это потребляет «NewsHandler», и это потребляет «NewsRepository», каждый из которых установлен в конструкторе потребителей. Как мне настроить и вернуть объект нижнего уровня? I.e репозиторий новостей? – user1352057

+1

Вы можете настроить единство, чтобы ввести правильный репозиторий, то есть «unitContainer.RegisterType ()», тогда при разрешении фасада репозиторий будет введен в обработчик новостей, который будет введен в фасад. – Lukazoid

Смежные вопросы