在构造函数中实现带有参数的控制器

4
我有许多不总是静态的值(标语、横幅、描述等)和PartialViews(block_head、block_footer、block_right),需要在哪里显示。因此,我需要在每个操作中将这些值的大集合传递到部分视图中,这对我来说不太好。
我在这里找到了一个有趣的解决方案:http://www.asp.net/mvc/tutorials/passing-data-to-view-master-pages-cs,在“好的解决方案”部分中。我可以将所有这些值的初始化移动到ApplicationController中,并从我的控制器实现它。
但是,我想继续在ApplicationController中初始化我的接口 :) 如果我能做到这一点,我认为这将是很棒的。我使用Ninject,所以,一些代码:
public abstract class ApplicationController : Controller
{
    //
    // GET: /Application/
    private readonly IModuleRepository _moduleRepository;
    public IModuleRepository moduleRepository
    {
        get { return _moduleRepository; }
    }

    public ApplicationController(IModuleRepository moduleRepository)
    {
        _moduleRepository = moduleRepository;

        foreach (var module in _moduleRepository.GetAllModules())
            ViewData[module.name] = module.value;
    }
}

实现:

public class HomeController : ApplicationController
{
    //I can use here moduleRepository without HomeController initialization
}

只有一个问题,我不知道如何实现ApplicationController,如果它有参数。这是一个好方法吗?是否有解决方案来解决我的问题?未来我将设置5-7个接口,并拥有大约10-15个控制器,因此在ApplicationController中初始化它们并在其他地方实现可能非常好。谢谢,如果问题很愚蠢,请原谅。


好的,添加:

现在,如果我有10个接口,应该像这样:

public class HomeController
{
    private IModuleRepository _moduleRepository;
    private IBookRepository _bookRepository;
    private ITableRepository _tableRepository;
    private IClassRepository _classRepository;
    private IRoomRepository _roomRepository;
    private IUserRepository _userRepository;
    private IWindowRepository _windowRepository;
    private IChairRepository _chairRepository;
    private IDoorRepository _doorRepository;
    private IWCRepository _wcRepository;

    public HomeController(IModuleRepository moduleRepository, IBookRepository bookRepository, ITableRepository tableRepository, IClassRepository classRepository, IRoomRepository roomRepository, IUserRepository userRepository, IWindowRepository windowRepository, IChairRepository chairRepository, IDoorRepository doorRepository, IWCRepository wcRepository)
    {
        _moduleRepository = moduleRepository;
        _bookRepository = bookRepository;
        _tableRepository = tableRepository;
        _classRepository = classRepository;
        _roomRepository = roomRepository;
        _userRepository = userRepository;
        _windowRepository = windowRepository;
        _chairRepository = chairRepository;
        _doorRepository = doorRepository;
        _wcRepository = wcRepository;
    }

    public ActionResult Index()
    {
        ViewBag.Windows = _windowRepository.GetAllWindows();
        ViewBag.Doors = _doorRepository.GetAllDoors();
        // e.t.c.

        return View();
    }
} 

我需要在每个需要使用这些Repositories(Home、Admin等)的控制器中初始化它们。

因此,如果我能做出类似于以下的东西:

public class HomeController : ApplicationController
{
    public ActionResult Index()
    {
        ViewBag.Windows = windowRepository.GetAllWindows();
        ViewBag.Doors = doorRepository.GetAllDoors();

        return View();
    }
}

在这里只需初始化一次:

public abstract class ApplicationController : Controller
{
    public ApplicationController(IModuleRepository moduleRepository, IBookRepository bookRepository, ITableRepository tableRepository, IClassRepository classRepository, IRoomRepository roomRepository, IUserRepository userRepository, IWindowRepository windowRepository, IChairRepository chairRepository, IDoorRepository doorRepository, IWCRepository wcRepository)
    {
        // Initialize repositories just one time here
    }
}

这个功能很不错,但我需要在实现类的构造函数中传递参数。

3个回答

3

看起来你可能在谈论构造函数注入。你的子类型的构造函数可以调用基类型的构造函数,以便注入IModuleRepository。

public class HomeController : ApplicationController
{

    public HomeController(IModuleRepository moduleRepository) : base(moduleRepository)
    {
      //other constructor code here
    }

    public HomeController() : this(null)
    {
      //default constructor
    }

}


public abstract class ApplicationController : Controller
{

  public IModuleRepoistory _moduleRepository { get; private set; }

  public ApplicationController(IModuleRepository moduleRepository)
  {
    _moduleRepository = moduleRepository ?? new DefaultModuleRepository();

    //...
  }
}

如果将来你想要注入许多接口,那么最好使用 Setter Injection


不,这不是我想做的。 - FSou1
1
我很抱歉误解了你的问题,你可能需要更清楚地表达你的问题才能得到更好的答案。 - David Glenn
是的,抱歉。现在我理解了你的答案,看起来不错。无论如何,在基类中传递IModuleRepository比定义字段、在每个构造函数中初始化等更好。谢谢,这真的很好。 - FSou1

1

您可以始终使用Ninject依赖项解析器来获取实例,而不是_:

public ApplicationController(IModuleRepository moduleRepository, IBookRepository bookRepository, ITableRepository tableRepository, IClassRepository classRepository, IRoomRepository roomRepository, IUserRepository userRepository, IWindowRepository windowRepository, IChairRepository chairRepository, IDoorRepository doorRepository, IWCRepository wcRepository)
    {
        // Initialize repositories just one time here
    }

你可以这样做

protected readonly IModuleRepository ModuleRepository;
// same for the rest...    

public ApplicationController()
{
    this.ModuleRepository = MvcApplication.Container.Get<IModuleRepository>();
    // same for rest or your modules.
}

如果你在使用MVC3,那么代码应该是:

protected readonly IModuleRepository ModuleRepository;

public ApplicationController()
{
    this.ModuleRepository = DependencyResolver.Current.GetService<IModuleRepository>();
    // same for rest or your modules.
}

1

是的,这个答案比第一个答案好,因为现在我有:

public abstract class ApplicationController : Controller
{
    protected readonly IModuleRepository _moduleRepository;
    public IModuleRepository moduleRepository
    {
        get { return _moduleRepository; }
    }

    public ApplicationController()
    {
        this._moduleRepository = DependencyResolver.Current.GetService<IModuleRepository>();

        foreach (var module in _moduleRepository.GetAllModules())
            ViewData[module.name] = module.value;

    }
}

我不需要在我的控制器中进行任何更改,只需实现并可以使用存储库:

public class HomeController : ApplicationController
{
    public ActionResult Index()
    {
        ViewBag.Modules = moduleRepository.GetAllModules();
        return View();
    }
}

在我所有的控制器中,我都有完整的ViewData值集合,可以在PartialViews中传递。非常感谢,太棒了 :)!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接