的JavaScript的表示我有我的码数[Flags]
枚举我想呈现给JavaScript没有复制粘贴&。 SignalR似乎正在通过将URL映射到返回由反射生成的JavaScript存根的Action来为Hub代理做类似的事情。由于代码是在运行时生成的,它似乎不可能包含在Bundles中。生成枚举
作为替代,我实现了一个T4模板来生成在设计时js文件:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="EnvDte" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".js" #>
Enums = {
<#
var visualStudio = (Host as IServiceProvider).GetService(typeof(EnvDTE.DTE))
as EnvDTE.DTE;
var project = visualStudio.Solution.FindProjectItem(this.Host.TemplateFile)
.ContainingProject as EnvDTE.Project;
foreach(EnvDTE.ProjectItem item in GetProjectItemsRecursively(project.ProjectItems))
{
if (item.FileCodeModel == null) continue;
foreach(EnvDTE.CodeElement elem in item.FileCodeModel.CodeElements)
{
if (elem.Kind == EnvDTE.vsCMElement.vsCMElementNamespace)
{
foreach (CodeElement innerElement in elem.Children)
{
if (innerElement.Kind == vsCMElement.vsCMElementEnum)
{
CodeEnum enu = (CodeEnum)innerElement;
#> <#= enu.Name #>: {
<#
Dictionary<string, string> values = new Dictionary<string, string>();
foreach (CodeElement child in enu.Members)
{
CodeVariable value = child as CodeVariable;
if (value != null) {
string init = value.InitExpression as string;
int unused;
if (!int.TryParse(init, out unused))
{
foreach (KeyValuePair<string, string> entry in values) {
init = init.Replace(entry.Key, entry.Value);
}
init = "(" + init + ")";
}
values.Add(value.Name, init);
WriteLine("\t\t" + value.Name + ": " + init + ",");
}
}
#>
},
<#
}
}
}
}
}
#>
};
<#+
public List<EnvDTE.ProjectItem> GetProjectItemsRecursively(EnvDTE.ProjectItems items)
{
var ret = new List<EnvDTE.ProjectItem>();
if (items == null) return ret;
foreach(EnvDTE.ProjectItem item in items)
{
ret.Add(item);
ret.AddRange(GetProjectItemsRecursively(item.ProjectItems));
}
return ret;
}
#>
但是这种感觉与EnvDTE
脆弱。特别是处理枚举的逻辑如:
[Flags]
public enum Access
{
None = 0,
Read = 1,
Write = 2,
ReadWrite = Read | Write
}
与复合值是一个脏字符串替换。上面的T4模板将生成:
Enums = {
Access: {
None: 0,
Read: 1,
Write: 2,
ReadWrite: (1 | 2),
},
};
有一个更清洁的方式来实现这一目标?理想情况下,某种设计时反射来生成js文件,因此可用于捆绑。
我认为甚至比基于T4的方法我在这个问题meantioned糟糕的是,因为你不仅要围绕复制和粘贴的东西,但要访问一个神奇的URL在浏览器,然后重新编译(!)复制和粘贴后,T4只需要右键单击 - >运行自定义工具 – mensi
不需要重新编译。只需浏览器刷新。没有神奇的URL,这是调试时可见的链接。这实际上工作得很好,并且已经得到了我工作过的几个团队的好评。 T4模板代码往往相当深奥,脆弱,难以维护。我已经使用了这两种方法,并发现自定义属性解决方案效率更高。 –