gpt4 book ai didi

asp.net - MEF 和 ASP.NET MVC

转载 作者:行者123 更新时间:2023-12-02 13:16:46 27 4
gpt4 key购买 nike

我想将 MEF 与 asp.net mvc 一起使用。我写了以下 Controller 工厂:

public class MefControllerFactory : DefaultControllerFactory
{
private CompositionContainer _Container;

public MefControllerFactory(Assembly assembly)
{
_Container = new CompositionContainer(new AssemblyCatalog(assembly));
}



protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType != null)
{
var controllers = _Container.GetExports<IController>();

var controllerExport = controllers.Where(x => x.Value.GetType() == controllerType).FirstOrDefault();

if (controllerExport == null)
{
return base.GetControllerInstance(requestContext, controllerType);
}

return controllerExport.Value;
}
else
{
throw new HttpException((Int32)HttpStatusCode.NotFound,
String.Format(
"The controller for path '{0}' could not be found or it does not implement IController.",
requestContext.HttpContext.Request.Path
)
);
}
}
}

在 Global.asax.cs 中,我正在设置我的 Controller 工厂:

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterRoutes(RouteTable.Routes);

ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory.MefControllerFactory(Assembly.GetExecutingAssembly()));
}

我有一个区域:

[Export(typeof(IController))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller
{
private readonly IArticleService _articleService;

[ImportingConstructor]
public HomeController(IArticleService articleService)
{
_articleService = articleService;
}

//
// GET: /Articles/Home/

public ActionResult Index()
{
Article article = _articleService.GetById(55);

return View(article);
}

}

IArticleService 是一个接口(interface)。

有一个类实现 IArticleService 并将其导出。

它有效。

这就是我使用 MEF 所需的一切吗?

如何跳过 Controller 的 PartCreationPolicyImportingConstructor 设置?

我想使用构造函数设置我的依赖项。

当缺少 PartCreationPolicy 时,我收到以下异常:

A single instance of controller 'MvcApplication4.Areas.Articles.Controllers.HomeController' cannot be used to handle multiple requests. If a custom controller factory is in use, make sure that it creates a new instance of the controller for each request.

最佳答案

你的技术非常可靠,即使在部分信任的情况下也能发挥作用。 nerd dinner MEF示例的扩展允许您按照约定处理发现 Controller 并自动将它们放入 MEF 导出中,而无需使用 MEF 属性标记它们。但是直接管理零件目录在部分信任中不起作用,因此 Nerd 晚餐 MEF 技术在部分信任中不起作用。

如果您完全信任地工作,并且希望 Controller 进行基于约定的发现,请从 Nerddinner MEF 示例开始,但您可能还应该阅读有关 nerddinner MEF 示例的几个主要问题,如果您的自己的应用程序的模型位于库项目的单独类中。我blogged about those cases并提出了一些修复建议。

如果您对基于惯例的发现内容不太感兴趣,那么 Nerd 晚餐样本就有点过度设计了。您的解决方案可能原样就很好......并且也可以在部分信任的情况下工作,这始终是一个好处。

[更新]我确实发现了您的技术的一个潜在问题:

var controllerExport = controllers.Where(x => x.Value.GetType() == 
controllerType).FirstOrDefault();

在此处的 where 子句中,您在部件集合中的每个导出上调用 .Value...这实际上会导致每个导出被组合并实例化以便进行评估。这可能是一个严重的性能问题。

您可以考虑使用命名导出合约来装饰您的 Controller ,如下所示:

[Export("Home", typeof(IController))]

然后使用像这样的 Controller 工厂:

public class MefControllerFactory: IControllerFactory
{
private CompositionContainer _Container;

public MefControllerFactory(Assembly assembly)
{
_Container = new CompositionContainer(new AssemblyCatalog(assembly));
}

#region IControllerFactory Members

public IController CreateController(RequestContext requestContext, string controllerName)
{

var controller = _Container.GetExportedValue<IController>(controllerName);

if (controller == null)
{
throw new HttpException(404, "Not found");
}

return controller;
}

public void ReleaseController(IController controller)
{
// nothing to do
}

#endregion
}

关于asp.net - MEF 和 ASP.NET MVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3033697/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com