【问题标题】:How can I generate a downloadable c# class from within an ASP.NET MVC website?如何从 ASP.NET MVC 网站中生成可下载的 c# 类?
【发布时间】:2012-09-20 13:39:07
【问题描述】:

我敢肯定这是一个非常奇怪的要求,但还是这样吧。

我们有一些客户配置代码,这些代码由我们编译到类库中的 C# 类表示。创建这些配置类目前是我想分配给开发人员以外的其他人的猴子工作。因此,我们正在构建一个“配置器”网站,业务分析师可以使用该网站来生成有效的 C# 类,方法是填写一个选择了相关选项的表单。

从 MVC 网站中的模板生成 C# 类的最佳方法是什么?请注意,我在这里不是在谈论在运行时动态生成和执行一个类:我们实际上是在生成一个文本文件,该文件恰好包含将包含在一个完全不同的项目中的 C# 代码。

这被证明是一个很难正确谷歌的话题!到目前为止出现的选项...

  • 只需使用标记化的文本文件并使用 String.Format 替换值
  • 以某种方式使用 Razor 作为模板引擎(但不确定如何使用,而且我们生成的不是 html)
  • 不知何故使用 T4 模板(至少我知道它是用来生成 C#,但不确定如何在运行时执行)

关于如何最好地解决这个问题的任何想法?

根据要求,这是输出类/文件的示例。此处的值会覆盖带有客户特定标签、验证等的基类中设置的值。这就是我们为客户定制产品的方式。

public class AreaRiskTemplate: AreaRiskTemplateBase
{
    public override string EntityName { get { return "risk"; } }
    public override string EntityNamePlural { get { return "risks"; } }
    public override string EntityNameArticle { get { return "a"; } }
    public override string CGovItemRefPrefix { get { return "R"; } }
    public override void SetFieldDefinitions()
    {

        FieldDefinitions.Level1.IsImplemented = true;
        FieldDefinitions.Level1.Label = "Category";
        FieldDefinitions.Level1.IsVisibleInGrid = true;

        FieldDefinitions.Level2.IsImplemented = true;
        FieldDefinitions.Level2.Label = "Team";
        FieldDefinitions.Level2.IsVisibleInGrid = true;

        FieldDefinitions.Description.IsImplemented = true;
        FieldDefinitions.Description.Label = "Description";
        FieldDefinitions.Description.IsVisibleInGrid = true;

    }
    public override ModelStateDictionary Validate()
    {
        var msd = new ModelStateDictionary();
        // add template-specific validation here
        msd.Merge(base.Validate());
        return msd;
    }
    public override List<string> Level1Options
    {
        get
        {
            return new List<string>
                {
                    "Organisational",
                    "Financial",
                    "Operational",
                    "External",
            "IT"
                };
        }
    }
}

更新:目前正在http://msdn.microsoft.com/en-us/library/ee844259(v=vs.100).aspx 调查 T4 模板(感谢下面的 cmets)。看起来很有希望。

【问题讨论】:

标签: c# asp.net-mvc templates razor t4


【解决方案1】:

我建议避开该网站,而直接使用 CodeSmith。您可以设计 CodeSmith 脚本,以便它会询问信息,然后生成所需的代码。看起来工作量少了很多,尽管你必须购买 CodeSmith。

【讨论】:

  • 感谢您的建议。我过去使用过很多 Codesmith。我想我的问题是,在这种情况下,我希望非技术人员输入允许生成类的数据。然后,开发人员将根据该数据登录并下载课程。自从我上次玩以来,Codesmith 的范围很可能在 5 年多的时间里发生了变化,但我认为它缺少输入界面。
  • @centralscru - CodeSmith 允许您创建一个对话框来接受生成时使用的参数。最终用户只需运行脚本,填写方框,然后单击确定。然后,您可以将这些生成的类保存到 UNC 共享中。
【解决方案2】:

以最少开销执行此操作的方法是使用 Microsoft 内置的 CodeDOM API。它允许您使用跨语言兼容的文档对象模型构建和操作 CLR 代码文档。

这种方法的唯一缺点是如何实现某些特定于语言的功能并不是很明显。一个示例是 C# readonly 字段,因为它们并非在所有 CLR 语言中都可用,而仅在 C# 中可用。这种特殊复杂性的解决方案是使用CodeSnippet 并将手动代码作为字符串插入。其他更复杂的不匹配问题可以通过将 CodeDOM 与模板引擎集成来缓解。 Oleg Sych 写了a useful article on integrating CodeDOM with the T4 templating engine。与纯文本生成方法相比,我更喜欢这种方法,因为强类型文档对象模型比纯文本更不容易出错。

此外,如果您确实想要编译输出代码,CodeDOM API 也支持这一点。

如果您认为这种做法可能会经常使用,您可能希望使用builder pattern 将一些常见的 DOM 操作功能包装到流畅的方法调用中。我建立了一个使用这种方法的个人库,它通过代码生成非常成功地提高了我的工作效率。

【讨论】:

    猜你喜欢
    • 2011-11-17
    • 2013-01-04
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 2013-07-18
    相关资源
    最近更新 更多