ASP.NET MVC 3 RC AreaRegistration.RegisterAllAreas()和动态加载的程序集 [英] ASP.NET MVC 3 RC AreaRegistration.RegisterAllAreas() and dynamically loaded assemblies

查看:1236
本文介绍了ASP.NET MVC 3 RC AreaRegistration.RegisterAllAreas()和动态加载的程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在与ASP.NET MVC 3 RC动态加载试验区。我已经看到了写在很多地方,这不是什么区用于和(至少pre-MVC 2)不可能,说<一href=\"http://weblogs.asp.net/rashid/archive/2009/12/30/asp-net-mvc-2-and-why-dynamic-area-is-not-supported.aspx\"相对=nofollow>这里例子。

但仍然!它应该能够得到它的工作,对不对?我创建了一个解决方案,增加了一个MVC 3项目,新增面积和一些内容。一切工作正常。现在,我创建了一个新的类库项目(在相同的解决方案),添加从MVC项目对它的引用,并开始在移动领域的相关部件库中。改变库项目的MVC项目的区域文件夹的输出目录,并确保的观点和他们的web.config文件复制到输出文件夹中。

阅读了很多关于怎么可能不具有外部区域后,这是一个有点令人惊讶的是这个工作。一点问题都没有真的!当我删除项目之间的引用,而是加载code库中的问题开始。 (调用之前 AreaRegistration.RegisterAllAreas())。现在这是行不通的。在所有。

我已经打探了一下在源MVC 3,这个问题似乎与<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.compilation.buildmanager.getreferencedassemblies.aspx\"相对=nofollow> BuildManager.GetReferencedAssemblies() 用来获取组件寻找 AreaRegistration

现在,我不是100%肯定这一点,但它好像这个方法只着眼于为$组件p $ psent /在编译时引用的,有人可以确认这是否是如此之<? / p>

我已经通过这个调试,并且该方法调用确实找不到我只是调用它之前加载的程序集。这可能是因为别的东西,我已经错过了也许..任何想法?


解决方案

事物的工作方式有点复杂。

GetReferencedAssemblies 引用包括组件,而不是加载的程序集。这包括:


  • 在您的应用程序的web.config中引用的所有组件(如 System.Web.Mvc

  • 一切从根web.config,其中包括像系统事情的System.Web 和其他人继承你不必自己添加。 (你可以在这里看看名单: C:\\ WINDOWS \\ Microsoft.Net \\框架\\ v4.0.30319 \\ web.config中)。
    它还包含了一个特殊的 * 项,

  • 包括一切都在您的网站文件夹

所以,现在把你的应用程序V1(一切都在一个单一的应用程序)。一切工作,因为应用程序code被编译成被自动包含在bin文件夹。此外,所有的区域意见等都是在应用程序本身,使他们可以访问。

在应用V2

现在(不同的项目有一个凸出到凸出参考自定义生成的任务,副本的意见,正确的位置在主应用程序)都仍然有效,因为默认情况下一个PROJ到凸出引用意味着类库二进制被复制到你的应用程序的bin文件夹。因此,按上述规则,面积code仍然得到正确加载。你已经设置库的输出路径的事实是你的主要应用的领域文件夹中的某些位置没有真正发挥作用 - 你刚刚结束与二进制的两个副本

现在在应用程序V3(无凸出,凸出裁判,区图书馆装配手动加载)您的库程序集被载入为时已晚。到时候你code运行为引用的程序集已经被锁定,不能再进行更改。

有就是运行code和项目添加到注册组件列表的方式:你可以用它做的<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.compilation.buildmanager.addreferencedassembly.aspx\"><$c$c>AddReferencedAssembly方法,它的必须的从<一个被调用href=\"http://haacked.com/archive/2010/05/16/three-hidden-extensibility-gems-in-asp-net-4.aspx\"><$c$c>$p$pApplicationStartMethodAttribute方法。

当然,你还是要对付你如何管理你的视图文件。您目前有它设置的方式是pretty多就等于拥有了在主应用程序的意见(因为他们得到有效复制到正确的位置)。

I am currently experimenting with dynamically loaded areas with ASP.NET MVC 3 RC. I've seen it written in many places that this is not what areas are intended for, and (at least pre-MVC 2) not possible, say here for example.

But still! It should be possible to get it to work, right? I've created a solution, added a MVC 3 project, added an area and some content. All is working well. Now I created a new class library project (in the same solution), added a reference to it from the MVC-project, and started moving over the area-related parts to the library. Changed the output-directory of the library project to the area-folder of the MVC-project, and made sure the Views and their web.config are copied to the output-folder.

After reading so much about how you couldn't have external areas, it was a little surprising that this worked. No problem at all really! The problem starts when I remove the reference between the projects, and instead load the library in code. (Before calling AreaRegistration.RegisterAllAreas().) Now it doesn't work. At all.

I've been poking around a bit in the source for MVC 3, and the problem seems to be with BuildManager.GetReferencedAssemblies() which is used to get the assemblies to look for implementations of AreaRegistration.

Now, I'm not 100% sure about this, but it seems as if this method only looks at assemblies that were present/referenced at compile-time, can someone confirm if this is in fact so?

I have debugged through this, and that method-call does indeed not find the assembly I loaded just before the call to it. It might be because of something else that I've missed perhaps.. Any ideas?

解决方案

The way things work is a bit complicated.

GetReferencedAssemblies includes referenced assemblies, not loaded assemblies. This includes:

  • all assemblies referenced in you application's web.config (such as System.Web.Mvc)
  • everything inherited from root web.config, which includes things like System, System.Web and others that you do not have to add yourself. (You can take a look at the list here: C:\Windows\Microsoft.Net\Framework\v4.0.30319\web.config).
    It also contains a special * item, which:
  • includes everything in your site's bin folder

So now take your app v1 (everything in a single app). Everything works because the application code gets compiled into the bin folder which gets automatically included. Also, all of the area views etc are in the application itself so they are accessible.

Now in app v2 (different project with a proj-to-proj reference and a custom build task that copies the views to the right location in your main app) everything still works, because by default a proj-to-proj references means that the class library binary gets copied to your app's bin folder. So by the above rules, the area code still gets loaded correctly. The fact that you've set the library's output path to be some location within your main app's Areas folder does not actually make a difference - you just end up with two copies of the binary.

Now in app v3 (no proj-proj ref, area library assembly loaded manually) your library assembly gets loaded too late. By the time your code runs the set of referenced assemblies has already been locked and can no longer be changed.

There is a way to run code and add items to the list of registered assemblies: you can do it using the AddReferencedAssembly method which must be invoked from a PreApplicationStartMethodAttribute method.

Of course you still have to deal with how you manage your view files. The way you currently have it set up is pretty much the same as having the views in the main application (since they effectively get copied into the right location).

这篇关于ASP.NET MVC 3 RC AreaRegistration.RegisterAllAreas()和动态加载的程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆