gpt4 book ai didi

c# - 另一个程序集中的 MVC 6 RC2 Controller

转载 作者:太空狗 更新时间:2023-10-29 17:44:26 25 4
gpt4 key购买 nike

在 MVC 6 RC1 中,我们使用 IAssemlbyProvider 接口(interface)来注册在运行时发现的程序集,并在类似的 fashion to this post 中注入(inject)额外的 Controller 类型。 .. 现在随着 RC2 版本的发布,IAssemblyProvider 已被删除并更改为 (see reference) .

我们的框架版本目前是net46

自升级以来,我们在外部程序集(未引用)中的 Controller 正在返回 404 状态。

我们已经尝试通过 ApplicationPartManager 手动将 Controller 添加到已注册的 Controller 。

var mvcBuilder = services.AddMvc();
var controllerFeature = new ControllerFeature();
mvcBuilder.PartManager.PopulateFeature(controllerFeature);

var moduleControllers = ModulesManager.GetControllers();
foreach (var c in moduleControllers)
controllerFeature.Controllers.Add(c);

mvcBuilder.PartManager.PopulateFeature(controllerFeature);

和...

services.AddMvc().ConfigureApplicationPartManager(app =>
{
var controllerFeature = new ControllerFeature();
app.PopulateFeature(controllerFeature);

var moduleControllers = ModulesManager.GetControllers();
foreach (var c in moduleControllers)
controllerFeature.Controllers.Add(c);

app.PopulateFeature(controllerFeature);
});

现在程序集确实已加载到 AppDomain 中,因为我们的依赖注入(inject)系统正在为外部程序集中的其他项目查找和填充服务。

在我们之前的实现中,使用 IAssemblyProvider 效果很好。

public class ModuleAwareAssemblyProvider : IAssemblyProvider
{
private readonly DefaultAssemblyProvider _defaultProvider;

public ModuleAwareAssemblyProvider(DefaultAssemblyProvider defaultProvider)
{
_defaultProvider = defaultProvider;
}

public IEnumerable<Assembly> CandidateAssemblies
{
get
{
return _defaultProvider.CandidateAssemblies.Concat(ModulesManager.Assemblies).Distinct();
}
}
}

我知道 RC2 仍然相对较新,但如果有人有任何经验,在启动时注册额外的 Controller 会有所帮助。

干杯,尼科

最佳答案

在直接使用 ControllerFeature 一段时间后没有结果,是时候回到基础了。

基本上在应用程序启动时, Controller 被注册到 Controller 功能容器而不是 Controller 功能。这是关键,因为您需要注册 Controller 。

我正在浏览 GitHub repository for RC2并遇到了 ControllerFeatureProvider .如前所述。

Discovers controllers from a list of <see cref="ApplicationPart"/>

然后在 PopulateFeature 下有一个方法,我们可以看到它抓取注册到应用程序的所有部分并提取 Controller 接口(interface)(IsController() 方法)值得回顾)。

/// <inheritdoc />
public void PopulateFeature(
IEnumerable<ApplicationPart> parts,
ControllerFeature feature)
{
foreach (var part in parts.OfType<IApplicationPartTypeProvider>())
{
foreach (var type in part.Types)
{
if (IsController(type) && !feature.Controllers.Contains(type))
{
feature.Controllers.Add(type);
}
}
}
}

现在我们知道 Controller 是如何找到的,它们来自 ApplicationPart注册到应用程序。下一个问题是我们如何创建应用程序部分

经过一些审查并尝试使用依赖注入(inject),手动将部件添加到应用程序以注册我的部件后,我遇到了另一个概念。

界面IMvcBuilder有扩展方法 AddApplicationPart它将 Assembly 添加到应用程序部分。这是通过将程序集包装在 AssemblyPart 中来完成的。应用部分。在查看 AssemblyPart 时,该部分将在程序集中找到的所有类型返回到调用部分系统(在我们的示例中为 ControllerFeatureProvider)。

/// <inheritdoc />
public IEnumerable<TypeInfo> Types => Assembly.DefinedTypes;

AssemblyPart 的一些有趣之处在于方法 GetReferencePaths()

/// <inheritdoc />
public IEnumerable<string> GetReferencePaths()
{
var dependencyContext = DependencyContext.Load(Assembly);
if (dependencyContext != null)
{
return dependencyContext.CompileLibraries.SelectMany(library => library.ResolveReferencePaths());
}

// If an application has been compiled without preserveCompilationContext, return the path to the assembly
// as a reference. For runtime compilation, this will allow the compilation to succeed as long as it least
// one application part has been compiled with preserveCompilationContext and contains a super set of types
// required for the compilation to succeed.
return new[] { Assembly.Location };
}

看来拼图的最后一 block 是在模块(或外部程序集的)project.json 文件中启用 preserveCompilationContext

"preserveCompilationContext": {
"type": "boolean",
"description": "Set this option to preserve reference assemblies and other context data to allow for runtime compilation.",
"default": false
}

最终实现和解决这个问题变得非常简单。我们的每个外部程序集(或模块)都通过我们的 ModuleManager 类加载。这有一个所有引用模块程序集的列表。因此,在注册 MVC 的 Startup.cs 文件中的 ConfigureServices 方法中,我们只需为每个模块程序集调用扩展方法 AddApplicationPart as。

var mvcBuilder = services.AddMvc();
foreach(var module in ModulesManager.ReferencedModules)
{
mvcBuilder.AddApplicationPart(module.ReferencedAssembly);
}

进行这些小的更改后,我的外部 Controller 将停止返回 404

关于c# - 另一个程序集中的 MVC 6 RC2 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37608298/

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