我认为这是非常可行的——但在我进入我的解决方案之前——请记住,捆绑是在第一次点击时创建并被重用——这意味着任何“动态”脚本仍然必须是全局的(即它不能依赖于特定用户等)。这就是为什么它通常只允许静态 js 文件。这么说...我可以想象这样一种情况,您可能想在您的 js 中粘贴版本号之类的变量(尽管在这种情况下,我个人只会使用 Ajax/JSON 来获取它)。
我认为解决方法是从Bundle创建派生类型。在其中,您将覆盖 EnumerateFiles 方法。最初,您将枚举 base.EnumerateFiles,然后包含您自己的虚拟文件。
类似的东西(注意:未经测试的代码):
public class VirtualMethodBundle : Bundle
{
private List<VirtualFile> _virtualContent = new List<VirtualFile>();
public override IEnumerable<VirtualFile> EnumerateFiles(BundleContext context)
{
foreach(var file in base.EnumerateFiles(context))
{
yield return file;
}
foreach(var virtual in _virtualContent)
{
yield return virtual;
}
}
public void AddCustomFile(VirtualFile file)
{
_virtualContent.Add(method);
}
}
然后你会有一个特殊的VirtualFile定义类型,它覆盖 Open/Name 方法并在那里返回你的动态内容......类似的东西。
public class MethodBasedVirtualFile : VirtualFile
{
private readonly Func<string> _contentFactory;
private readonly string _path;
public MethodBasedVirtualFile(string path, Func<string> contentFactory)
{
_path = path;
_contentFactory = contentFactory;
}
public override string Name { get { return _path; } }
public override Stream Open()
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(_contentFactory());
writer.Flush();
stream.Position = 0;
return stream;
}
}
那么使用它你将拥有的一切......
var bundle = new VirtualMethodBundle();
bundle.Include(... real files ...);
bundle.AddCustomFile(
new MethodBasedVirtualFile("~/DynamicScript/UrlDictionary",
... the method that creates the content of that script...)
);
如果你很聪明,你可以制作一个 UrlVirtualFile,它采用 url 路径并在需要时使用 MVC 自动获取内容。