我正在尝试使用区域设置MVC3解决方案,但我希望将我的区域放在不同的程序集中。例如,我想要一个包含母版页,样式表,脚本,登录页面等共享资源的父程序集。但我想在不同的程序集中使用不同的业务功能区域。
我尝试了为MVC2预览编写的示例:http://msdn.microsoft.com/en-us/library/ee307987%28VS.100%29.aspx。 (注意,我最初是从这个Stack Overflow线程中找到的:ASP.NET MVC - separating large app)。但似乎MVC3没有将视图文件移动到主项目中的选项。我对使用嵌入式资源/ VirtualPathProvider选项并不感到高兴。
有关如何使用MVC3的任何建议吗?
谢谢, 跳过
答案 0 :(得分:13)
1 - 将你的Mvc区域分成不同的Mvc项目,编译成他们自己的单独组件
2 - 将其添加到AssemblyInfo.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 - 从不同的Mvc(区域)项目注册您的区域
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/
答案 1 :(得分:2)
您可以在不使用区域的情况下分离控制器和视图。对于控制器,您可以使用Windsor或任何其他IoC容器来解析来自不同组件的控制器。 例如,您可以通过以下方式注册所有控制器:
container.Register(AllTypes.FromAssemblyInDirectory(new AssemblyFilter(HttpRuntime.BinDirectory)).BasedOn<IController>().Configure(c => c.LifeStyle.Transient));
此外,您必须实现IDependencyResolver,然后设置DependencyResolver.SetResolver(...)。
对于视图,您有两种选择:
我们使用Windsor和VirutalPathProvider实现提供的嵌入式资源视图构建了一个简单的框架(类似于Portable Areas)。
答案 2 :(得分:2)
您可以使用MvcContrib with Portable Areas,但这样您就可以使用嵌入式视图。
只需创建一个MVC和一个类库项目。在MVC项目中创建您的区域,并在完成后将除区域视图之外的所有内容移动到类库中。
使用NuGet进行打包,您可以在每个MVC项目中使用新的NuGet区域。
答案 3 :(得分:0)
有关如何创建在另一个MVC应用程序中作为Area工作的项目,请参阅this article。
基本上,区域项目中的文件位于主项目的Area
文件夹下,但不包含在主项目的一部分中(未在项目文件中引用)。