我找不到任何类似的问题,所以我写这篇文章。有私有字段IBaseClass的样本控制器。示例代码如下所示:
public class TmpController : Controller
{
private IBaseClass _baseClass;
public TmpController()
{
_baseClass = new BaseClass(this);
}
}
public interface IBaseClass
{
//...
}
public class BaseClass : IBaseClass
{
protected TmpController TmpController;
public BaseClass(TmpController tmpController)
{
TmpController = tmpController;
}
//IBaseClass implementation
}
我的问题是;如何使用Unity框架将BaseClass对象注入到TmpController的构造函数中? 我想让我的控制器"更苗条"。我想把关于验证的逻辑和准备我的控件的数据源(如comboBox等)放到不同的类中。我尝试在我的.Web项目中使用某种特定情况制作某种SOC,这将使我的控制器更易于阅读和维护。我每个视图使用一个控制器,但我遇到了非常复杂的形式。目前我有超过3000行代码的控制器,并且很难维护,所以我想用它做一些事情。 是的,我使用的是服务和存储库,但问题在于验证ViewModel,将ViewModel对象映射到DTO和向后,准备给定组件的数据源等。
答案 0 :(得分:0)
@Razem,您对我的评论的猜测是正确的。你描述的负点也是有效的。
您所问的“服务取决于控制器”肯定可以实现,但这将是一个糟糕的设计。
目前import mechanize
br = mechanize.Browser()
br.open("website")
仅依赖于BaseClass
。当您需要其他控制器中的TempController
时,您将如何处理该场景?代码将开始中断,您最终会向BaseClass
添加新的依赖项。
同样根据设计建议,顶层应该依赖于底层而不是反之亦然。
话虽如此,通过使控制器依赖于BaseClass
,您仍然可以实现您正在寻找的功能。
我不确定您在IBaseClass
内访问控制器所需的具体原因。在创建以下建议时我做了一些假设。其中一个假设是BaseClass
,BaseClass
和IBaseClass
类属于同一个程序集。
Controller
在//Have a BaseController Class with the properties and/or method which you will be using in the `BaseClass` class and make them virtual so that derived controller classes can override them to have specific implementation.
public class BaseController : Controller
{
public virtual string ControllerMethod()
{
return "Controller Method from Base Controller";
}
public virtual string RandomValue
{
get
{
return "Random value from Base Controller";
}
}
}
中创建一个方法,为其设置控制器。
IBaseClass
从public interface IBaseClass
{
void SetController(BaseController controller);
void Method1();
}
public class BaseClass : IBaseClass
{
private BaseController controller;
public void SetController(BaseController controller)
{
this.controller = controller;
}
public void Method1()
{
var str = this.controller.RandomValue;
}
}
派生TempController
并使其依赖于BaseController
。在IBaseClass
{@ 1}} TempController
方法的构造函数中,通过SetController
参数传递给它。您还可以在此处覆盖IBaseClass
的方法/属性。
在此之后,您可以调用this
的任何方法,而无需将控制器实例传递给它。
BaseController
在您的网络项目中安装nuget包 Unit.Mvc 。打开位于 App_Start 文件夹下的文件IBaseClass
,然后更改方法public class TempController : BaseController
{
private IBaseClass baseClass;
public HomeController(IBaseClass productService)
{
this.baseClass = productService;
this.baseClass.SetController(this);
}
public override string RandomValue
{
get
{
return "Random value from Derived Class.";
}
}
public ActionResult Index()
{
this.baseClass.Method1();
ViewBag.Title = "Home Page";
return View();
}
}
,如下所示。
Unity.Config
我确信我不需要解释它是如何起作用的。
P.S。 :您需要确保在控制器构造函数中调用RegisterTypes
方法,以避免在public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IBaseClass, BaseClass>(new PerRequestLifetimeManager());
}
中使用控制器时出现NullReferenceException。这是您需要采取的小开销,以实现良好和可维护的设计。