在asp.net-mvc中有没有更好的方法来实现IOC?
我有一个asp.net-mvc网站,我正在使用LinFu做IOC。我遇到了一个问题,许多操作都有一个依赖项,我想将其注入控制器,但我只想在调用依赖它的操作时初始化该依赖项 因此,在我的控制器中,我的控制器中有以下代码:在asp.net-mvc中有没有更好的方法来实现IOC?,asp.net-mvc,interface,inversion-of-control,linfu,Asp.net Mvc,Interface,Inversion Of Control,Linfu,我有一个asp.net-mvc网站,我正在使用LinFu做IOC。我遇到了一个问题,许多操作都有一个依赖项,我想将其注入控制器,但我只想在调用依赖它的操作时初始化该依赖项 因此,在我的控制器中,我的控制器中有以下代码: public PersonController { private IPeopleImporter _peopleImporter; public override void Initialize(LinFu.IoC.Interfaces.ISer
public PersonController
{
private IPeopleImporter _peopleImporter;
public override void Initialize(LinFu.IoC.Interfaces.IServiceContainer source)
{
_peopleImporter= source.GetService<IPeopleImporter>();
base.Initialize(source);
}
public JsonResult GetDetails(int id)
{
var p = _peopleImporter.Get(id);
var personDetails = new {p.Id, p.FirstName, p.LastName, StandardId = p.StandardIdLogin, p.PersonNumber};
return Json(personDetails);
}
}
这似乎是常见的模式/问题。是否有推荐的解决方案。同时,避免性能受到影响的另一种方法是简化控制器内部的concete实现,避免IOC?我通常通过将依赖项作为参数注入到我的操作中来解决这个问题。普通的或廉价的依赖项可以在类级别注入,而不寻常的或昂贵的依赖项可以作为参数注入 以下是企业库Unity的一些示例代码,但您可以对其进行调整:
public class UnityActionInvoker : ControllerActionInvoker
{
readonly IUnityContainer container;
public UnityActionInvoker(IUnityContainer container)
{
this.container = container;
}
protected override object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
{
Type parameterType = parameterDescriptor.ParameterType;
if (parameterType != typeof(string) && !parameterType.IsValueType && container.IsRegistered(parameterType))
{
return container.Resolve(parameterType).AssertNotNull();
}
return base.GetParameterValue(controllerContext, parameterDescriptor);
}
}
您可以通过在控制器的构造函数或所有控制器的公共基类中设置Controller.ActionInvoker来钩住此ControllerActionInvoker
以下是控制器的外观:
public PersonController
{
public JsonResult GetDetails(int id, IPeopleImporter _peopleImporter /*injected*/)
{
...
}
}
我通常通过将依赖项作为参数注入到我的操作中来解决这个问题。普通的或廉价的依赖项可以在类级别注入,而不寻常的或昂贵的依赖项可以作为参数注入 以下是企业库Unity的一些示例代码,但您可以对其进行调整:
public class UnityActionInvoker : ControllerActionInvoker
{
readonly IUnityContainer container;
public UnityActionInvoker(IUnityContainer container)
{
this.container = container;
}
protected override object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
{
Type parameterType = parameterDescriptor.ParameterType;
if (parameterType != typeof(string) && !parameterType.IsValueType && container.IsRegistered(parameterType))
{
return container.Resolve(parameterType).AssertNotNull();
}
return base.GetParameterValue(controllerContext, parameterDescriptor);
}
}
您可以通过在控制器的构造函数或所有控制器的公共基类中设置Controller.ActionInvoker来钩住此ControllerActionInvoker
以下是控制器的外观:
public PersonController
{
public JsonResult GetDetails(int id, IPeopleImporter _peopleImporter /*injected*/)
{
...
}
}
第一步是将此操作放入一个单独的控制器中。因此,您不必为此控制器中的其他操作支付初始化费用 然后使用真正的IoC模式,而不是您当前使用的被视为反模式的服务定位器。在IoC中,控制器不应该知道所使用的特定DI框架的任何信息。在IoC中,控制器接收所有依赖项作为构造函数参数
public PersonsController: Controller
{
private readonly IPeopleImporter _peopleImporter;
public PersonsController(IPeopleImporter peopleImporter)
{
_peopleImporter = peopleImporter;
}
public ActionResult GetDetails(int id)
{
var p = _peopleImporter.Get(id);
var personDetails = new { p.Id, p.FirstName, p.LastName, StandardId = p.StandardIdLogin, p.PersonNumber };
return Json(personDetails, JsonRequestBehavior.AllowGet);
}
}
第一步是将此操作放入一个单独的控制器中。因此,您不必为此控制器中的其他操作支付初始化费用 然后使用真正的IoC模式,而不是您当前使用的被视为反模式的服务定位器。在IoC中,控制器不应该知道所使用的特定DI框架的任何信息。在IoC中,控制器接收所有依赖项作为构造函数参数
public PersonsController: Controller
{
private readonly IPeopleImporter _peopleImporter;
public PersonsController(IPeopleImporter peopleImporter)
{
_peopleImporter = peopleImporter;
}
public ActionResult GetDetails(int id)
{
var p = _peopleImporter.Get(id);
var personDetails = new { p.Id, p.FirstName, p.LastName, StandardId = p.StandardIdLogin, p.PersonNumber };
return Json(personDetails, JsonRequestBehavior.AllowGet);
}
}
您可以在任务中使用下一个技巧。 您可以注入的不是IPeoplimPorter的实例,而是此类型的工厂:
private readonly Func<IPeopleImporter> _peopleImporterFactory;
例如:
public PersonController
{
}您可以在任务中使用下一个技巧。 您可以注入的不是IPeoplimPorter的实例,而是此类型的工厂:
private readonly Func<IPeopleImporter> _peopleImporterFactory;
例如:
public PersonController
{
}我不知道LinFu的情况,但许多其他IOC框架提供了工厂注入,可以在需要时用于实例化实例。您展示的不是IOC。你一定把这里的术语弄混了。在IoC中,控制器将依赖项作为构造函数参数。在您的示例中,您将控制器绑定到DI框架LinFu(在您的示例中),并且在您查询DI框架以检索依赖项的初始化方法中使用服务定位器模式。这被认为是一种反模式。我不知道LinFu,但许多其他IOC框架提供工厂注入,可以在需要时用于实例化实例。您展示的不是IOC。你一定把这里的术语弄混了。在IoC中,控制器将依赖项作为构造函数参数。在您的示例中,您将控制器绑定到DI框架LinFu(在您的示例中),并且在您查询DI框架以检索依赖项的初始化方法中使用服务定位器模式。这被认为是一种反模式。在IoC中,可以通过构造函数以外的其他方式注入依赖项。当然构造函数是最常见的,但不是唯一可能的mechanism@RuneFS是的,没错。您可以对非必需的依赖项使用属性注入。@Darin-我同意您的观点。考虑到Linfu似乎不支持适当的IOC,控制器不需要对IOC容器的引用,此时希望从Linfu迁移出去。在IOC中,您可以通过构造函数以外的其他方式注入依赖项。当然构造函数是最常见的,但不是唯一可能的mechanism@RuneFS是的,没错。您可以对非必需的依赖项使用属性注入。@Darin-我同意您的观点。考虑到Linfu似乎不支持适当的IOC,控制器不需要对IOC容器的引用,因此现在希望迁移到Linfu之外。