ASP.NET 视3RC AreaRegistration.RegisterAllAreas()和动态加载的程序集
-
27-09-2019 - |
题
我目前正在试验的动态加载的区域ASP.NET 视3RC。我已经看到了它写在许多地方,这不是什么领域都旨在为,以及(至少预软2)不能说 在这里, 例如。
但仍然!它应该是能获得它的工作,对吗?我已经创建了一个解决方案,添加一个视3个项目,增加了一个区域和一些内容。所有运作良好。现在我创造了一类新的图书馆项目(在同样的解决方案),增加了一个参考它从视项目,并开始移动超过该区域有关的部分图书馆。改变的产出目录的库项目的区域文件夹的视项目,并作出肯定的看法和他们的网络。config复制到输出的文件夹。
在阅读这么多关于如何,你不能有外部地区,这是一个有点令人惊讶的是这一工作。一点问题都没有是真的!问题开始的时候我除参考项目之间,而不是载于图书馆的代码。(话之前 AreaRegistration.RegisterAllAreas()
.) 现在它不工作。在所有。
我一直戳了一下周围的源视3,问题似乎是有 BuildManager.GetReferencedAssemblies()
这是用来获得大会,以寻找实现的 AreaRegistration
.
现在,我不是100%确定关于这一点,但这似乎是,如果这种方法只看集会,出/引用的在汇编时,有人可以确认,如果这实际上是这样的吗?
我已经试过这种方法叫做事实上不会找到我会装载之前的呼叫。这可能是因为别的东西,我已经错过了许..任何想法?
解决方案
事情的运作方式有点复杂。
GetReferencedAssemblies
包括引用的程序集,而不是加载的程序集。这包括:
- 应用程序的 web.config 中引用的所有程序集(例如
System.Web.Mvc
) - 从 root web.config 继承的所有内容,其中包括诸如
System
,System.Web
以及其他您不必自己添加的内容。(您可以在这里查看列表:C:\Windows\Microsoft.Net\Framework\v4.0.30319\web.config
).
它还包含一个特殊的*
项目,其中: - 包括您网站中的所有内容
bin
文件夹
现在使用您的应用程序 v1(所有内容都在一个应用程序中)。一切正常,因为应用程序代码被编译到自动包含的 bin 文件夹中。此外,所有区域视图等都位于应用程序本身中,因此可以访问它们。
现在在应用程序 v2 中(具有 proj-to-proj 参考的不同项目 和 将视图复制到主应用程序中正确位置的自定义构建任务)一切仍然有效,因为默认情况下,proj-to-proj 引用意味着类库二进制文件被复制到应用程序的 bin 文件夹。因此,根据上述规则,区号仍然可以正确加载。事实上,您将库的输出路径设置为主应用程序的 Areas 文件夹中的某个位置实际上并没有什么区别 - 您最终只会得到二进制文件的两个副本。
现在在应用程序 v3 中(没有 proj-proj 引用,手动加载区域库程序集),您的库程序集加载得太晚了。当您的代码运行时,引用的程序集集已被锁定并且无法再更改。
有一种方法可以运行代码并将项目添加到已注册程序集的列表中:你可以使用 AddReferencedAssembly
方法其中 必须 被调用从 PreApplicationStartMethodAttribute
方法.
当然,您仍然需要处理如何管理视图文件。您当前的设置方式与主应用程序中的视图几乎相同(因为它们有效地被复制到正确的位置)。
其他提示
1-你单独视领域进松根视项目被编入他们自己独立的集会
2-加这个给你的程序集信息.cs类,呼吁方法的应用程序时加载
[assembly: PreApplicationStartMethod(typeof(PluginAreaBootstrapper), "Init")]
3-这是什么Init方法看起来像时,它援引过负荷
public class PluginAreaBootstrapper
{
public static readonly List<Assembly> PluginAssemblies = new List<Assembly>();
public static List<string> PluginNames()
{
return PluginAssemblies.Select(
pluginAssembly => pluginAssembly.GetName().Name)
.ToList();
}
public static void Init()
{
var fullPluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Areas");
foreach (var file in Directory.EnumerateFiles(fullPluginPath, "*Plugin*.dll"))
PluginAssemblies.Add(Assembly.LoadFile(file));
PluginAssemblies.ForEach(BuildManager.AddReferencedAssembly);
}
}
4-加一个自定义RazorViewEngine
public class PluginRazorViewEngine : RazorViewEngine
{
public PluginRazorViewEngine()
{
AreaMasterLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
AreaPartialViewLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
var areaViewAndPartialViewLocationFormats = new List<string>
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
var partialViewLocationFormats = new List<string>
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
var masterLocationFormats = new List<string>
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
foreach (var plugin in PluginAreaBootstrapper.PluginNames())
{
masterLocationFormats.Add(
"~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
masterLocationFormats.Add(
"~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
masterLocationFormats.Add(
"~/Areas/" + plugin + "/Views/Shared/{1}/{0}.cshtml");
masterLocationFormats.Add(
"~/Areas/" + plugin + "/Views/Shared/{1}/{0}.vbhtml");
partialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
partialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
partialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Views/Shared/{0}.cshtml");
partialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Views/Shared/{0}.vbhtml");
areaViewAndPartialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
areaViewAndPartialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
areaViewAndPartialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Areas/{2}/Views/{1}/{0}.cshtml");
areaViewAndPartialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Areas/{2}/Views/{1}/{0}.vbhtml");
areaViewAndPartialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Areas/{2}/Views/Shared/{0}.cshtml");
areaViewAndPartialViewLocationFormats.Add(
"~/Areas/" + plugin + "/Areas/{2}/Views/Shared/{0}.vbhtml");
}
ViewLocationFormats = partialViewLocationFormats.ToArray();
MasterLocationFormats = masterLocationFormats.ToArray();
PartialViewLocationFormats = partialViewLocationFormats.ToArray();
AreaPartialViewLocationFormats = areaViewAndPartialViewLocationFormats.ToArray();
AreaViewLocationFormats = areaViewAndPartialViewLocationFormats.ToArray();
}
}
5-寄存器领域从不同的视(区域)项目
namespace MvcApplication8.Web.MyPlugin1
{
public class MyPlugin1AreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "MyPlugin1"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"MyPlugin1_default",
"MyPlugin1/{controller}/{action}/{id}",
new {action = "Index", id = UrlParameter.Optional}
);
}
}
}
源代码和其他参考可以可以在这里找到:http://blog.longle.io/2012/03/29/building-a-composite-mvc3-application-with-pluggable-areas