编译时进行C#代码扩展/注入

时间:2018-09-08 05:54:40

标签: c# .net code-injection

我正在寻找一种在编译时扩展/注入代码的方法, 类似于模板/宏/片段...

假设我在应用程序的很多地方都编写了这段代码:

[JsonObject("MyProperty")]
private string MyPropertyJson { get; set; }
public object MyProperty { get; set; }

MyPropertyJson属性仅用于EF映射,因此我将值保存为DB中的JSON字符串,但对于类用户,他们仅了解MyProperty属性。

我想做的是在编译时将MyPropertyJson扩展为:

private string MyPropertyJson 
{
    get
    {
        return JsonConvert.SerializeObject(MyProperty);
    }
    set
    {
        MyProperty = JsonConvert.DeserializeObject(value);
    }
}

我希望仅在输出二进制文件中完成此操作,而不会影响源代码。

我了解Unity,PostSharp,Aspect-Injector等。但是它们无法实现我想要的功能,因为通过使用它们,我必须使用一些反射来查找和操纵MyProperty,但是我想像对其进行扩展一样它是在同一个类中编写的,可以访问所有类的内部信息。

这与代码段完全一样,但是要在编译阶段进行扩展。

3 个答案:

答案 0 :(得分:0)

T4 aka Text Templates是在Visual Studio中受支持且不需要任何额外费用的解决方案。但是,这确实需要您安装所使用的VS版本的VS SDK(例如2015)和Modeling SDK(例如2015)。

对于我的base class libraries,我最终得到了dedicating an assembly的使用条款,以供我在生产代码中编写的T4代码中使用。我在诸如IO代码(例如.TT.CS)推出对原语的读/写操作的地方使用它。虽然如果不需要太多/复杂的编译时代码生成,则不必这样做。

答案 1 :(得分:0)

我能够通过编写BeforeBuild msbuild目标来调用我开发来的外部控制台应用程序来实现自己的要求

  1. 将要重写的源文件复制到临时文件夹中
  2. 在临时文件中重写源代码
  3. 在.csproj文件中添加了条件编译标签,以包含经过处理的源文件,而不是原始文件。

它就像一种魅力:)

我正在为此任务使用通用引擎,完成后将其提交到github。

答案 2 :(得分:0)

这是一种获得想要的东西的方法。

使用implicit operators

例如,需要创建自己的json对象类,然后添加以下内容:

class JsonObject {
    public object obj;

    public static implicit operator string(JsonObject target) { 
        return Json.SerializeObject(target.obj);
    }
}

但这并不能真正做到您真正想要的。几乎与创建新类和添加函数相同。