2015-10-06 2 views
3

Чтобы облегчить для себя модульное тестирование моего приложения, я пытаюсь реализовать шаблон репозитория, перемещая свои функции доступа к данным в отдельный класс репозитория.ASP MVC Controller не называется

Мой класс доступа к данным в моем хранилище:

public class ErrorRepository : IErrorRepository 
{ 
    public ErrorModel Errors { get; set; } 
    public List<ErrorModel> ErrorList { get; set; } 

    public List<ErrorModel> GetErrors() 
    { 
     string cs = "some path"; 

     using (SQLiteConnection con = new SQLiteConnection(cs)) 
     { 
      var listOfErrors = new List<ErrorModel>(); 
      string stm = "SELECT * FROM Error WHERE Checked == 'False'"; 
      con.Open(); 

      using (SQLiteCommand cmd = new SQLiteCommand(stm, con)) 
      { 
       using (SQLiteDataReader rdr = cmd.ExecuteReader()) 
       { 
        while (rdr.Read()) 
        { 
         listOfErrors.Add(new ErrorModel 
         { 
          Id = rdr["ID"].ToString() 
         }); 
        } 

        rdr.Close(); 
        ErrorList = listOfErrors; 
       } 
      } 

      con.Close(); 
     } 

     return ErrorList; 
    } 
} 

public interface IErrorRepository 
{ 
    List<ErrorModel> GetErrors(); 
} 

Мой контроллер:

public class ErrorController : Controller 
{ 
    private IErrorRepository _errorRepository; 

    public ErrorController(IErrorRepository errorRepository) 
    { 
     _errorRepository = errorRepository; 
    } 

    public ActionResult Error(int? page) 
    { 
     var errors = _errorRepository.GetErrors(); 

     //// stuff for paging 
     int pageSize = 10; 
     int pageNumber = (page ?? 1); // if there is no page, return page 1 

     return View(errors.ToPagedList(pageNumber, pageSize)); 
    } 
} 

Но дело в том, контроллер никогда не вызывается.

Я изменил его из предыдущей версии, где контроллер отвечал за все. Таким образом, все, что я сделал, это перенос данных, поступающих в отдельный класс. Представление «Ошибка» такое же, как и раньше. Я пропустил некоторые детали в моей реализации?

UPDATE:

Я возился с конструктором немного, и у меня есть несколько вопросов. Каким образом следующий код, где я впрыснуть его в конструктор не работает:

public ErrorController(IErrorRepository _errorRepository) 
    { 
     this._errorRepository = _errorRepository; 
    } 

Но если я могу изменить его к этому, контроллер будет вызываться, и все, кажется, работает нормально:

public ErrorController() 
    { 
     _errorRepository = new ErrorRepository(); 
    } 

Но не последний пример - это плохой способ сделать это, поскольку ErrorController по-прежнему тесно связан с ErrorRepository?

UPDATE 2:

Я сделал этот заказ контроллер завода:

public class ControllerFactory : DefaultControllerFactory 
{ 
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     try 
     { 
      if (controllerType == null) 
      { 
       throw new ArgumentNullException("controllerType"); 
      } 
      if (!typeof (IController).IsAssignableFrom(controllerType)) 
      { 
       throw new ArgumentException(string.Format("Type requested is not a controller: {0}", controllerType.Name), "controllerType"); 
      } 
      return MvcUnityContainer.Container.Resolve(controllerType) as IController; 
     } 
     catch (Exception) 
     { 
      return null; 
     } 
    } 
} 

public static class MvcUnityContainer 
{ 
    public static UnityContainer Container { get; set; } 
} 

И это загрузчика класс, чтобы установить все зависимости:

public class Bootstrapper 
{ 
    public static IUnityContainer Initialise() 
    { 
     var container = BuildUnityContainer(); 
     DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 

     return container; 
    } 

    private static IUnityContainer BuildUnityContainer() 
    { 
     var container = new UnityContainer(); 
     container.RegisterType<IErrorRepository, ErrorRepository>(); 
     MvcUnityContainer.Container = container; 

     return container; 
    } 
} 

который я затем инициализировать в Global. asax file:

 // Initialise IoC container 
     Bootstrapper.Initialise(); 
     // Register custom controller factory 
     ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory)); 

Теперь я могу использовать инъекции конструктор и тем самым разъединить мой ErrorController из моего ErrorRepository:

public ErrorController(IErrorRepository errorRepository) 
    { 
     this.errorRepository = errorRepository; 
    } 
+2

У вас есть какой-то IoC, который вводит 'IErrorController'? Скорее всего, он не попадет в контроллер, потому что у вас нет пустого конструктора и, вероятно, нет установки DI. – Johan

+0

Вы используете IoC для ввода 'IErrorRepository'? Как он создается? – Ric

+1

Что вы подразумеваете под «контроллер никогда не называется»? Какой запрос вы делаете и какой ответ вы получаете? – CodeCaster

ответ

0

Хорошо, что мне удалось это исправить, прочитав this отличный пост о том, как сделать IoC с Unity. Я обновил OP своим последним кодом.

0

По моему опыту, Ninject - хороший контейнер IoC. Вы можете загрузить и запустить мой проект ASP.NET MVC с here. Я использовал Injection Dependency от более низкого уровня к более высокому уровню. Надеюсь, это даст вам представление о структуре Ninject и почему мы поддерживаем принцип инверсии зависимостей

+0

Вы имеете в виду принцип зависимости от инверсии или принцип инверсии управления? lol – samneric

+0

Принцип инверсии зависимостей. Это делается с помощью инверсии управления. Инъекция зависимостей - это один из способов инвертировать элемент управления, поэтому мы поддерживаем принцип инверсии зависимостей. :) –

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