代码之家  ›  专栏  ›  技术社区  ›  Scott Stafford

如何在这里应用c中的“模板”或“框架”代码?

  •  2
  • Scott Stafford  · 技术社区  · 14 年前

    在我的业务层中,我需要许多遵循模式的方法:

    public BusinessClass PropertyName
    {
        get
        {
            if (this.m_LocallyCachedValue == null)
            {
                if (this.Record == null)
                {
                    this.m_LocallyCachedValue = new BusinessClass(
                         this.Database, this.PropertyId);
                }
                else
                {
                    this.m_LocallyCachedValue = new BusinessClass(
                         this.Database, this.Record.ForeignKeyName);
                }
            }
            return this.m_LocallyCachedValue;
        }
    }
    

    我仍在学习c,我正试图找出编写此模式一次的最佳方法,并将方法添加到遵循此模式的每个业务层类中,并替换适当的类型和变量名。

    businessclass是必须替换的类型名,propertyname、propertyid、foreignkeyname和m_locallycachedvalue都是应该替换的变量。

    属性在这里可用吗?我需要反思吗?如何在一个地方编写我提供的框架,然后只编写一两行包含替换参数的代码,并让模式传播自己?

    编辑:修改了我的误导性标题——我希望找到一个不涉及代码生成或复制/粘贴技术的解决方案,而是能够以某种形式在基类中编写一次代码的骨架,并将其“实例化”为许多子类,作为var的访问器欠条性质。

    编辑:这是我的解决方案,正如所建议的,但没有得到被选中的答案。

    // I'll write many of these...
    public BusinessClass PropertyName
    {
        get
        {
            return GetSingleRelation(ref this.m_LocallyCachedValue, 
                this.PropertyId, "ForeignKeyName");
        }
    }
    
    // That all call this.
    public TBusinessClass GetSingleRelation<TBusinessClass>(
        ref TBusinessClass cachedField, int fieldId, string contextFieldName)
    {
        if (cachedField == null)
        {
            if (this.Record == null)
            {
                ConstructorInfo ci = typeof(TBusinessClass).GetConstructor(
                    new Type[] { this.Database.GetType(), typeof(int) });
                cachedField = (TBusinessClass)ci.Invoke(
                    new object[] { this.Database, fieldId });
            }
            else
            {
                var obj = this.Record.GetType().GetProperty(objName).GetValue(
                    this.Record, null);
                ConstructorInfo ci = typeof(TBusinessClass).GetConstructor(
                    new Type[] { this.Database.GetType(), obj.GetType()});
                cachedField = (TBusinessClass)ci.Invoke(
                    new object[] { this.Database, obj });
            }
        }
    
        return cachedField;
    }
    
    3 回复  |  直到 14 年前
        1
  •  0
  •   Seth Petry-Johnson    14 年前

    您可以使用codesmith或mygeneration等对gen进行编码。您可能会将类和属性的列表存储在某个地方,然后将该数据传递给代码生成器。在编译解决方案之前,您可能需要研究使用预生成事件重新生成这些类。

    或者,可以将此功能烘焙到基类或帮助器方法中。

    public BusinessClass MyProperty
    {
        get { return GetCached("MyProperty", "PropertyId", "FKName", "LocalValue"); }
    }
    

    我会把尸体 GetCached() 取决于您,但它基本上与您发布的变量作为参数传入的内容相同。

    如果这些值中的任何一个对于类中的所有属性都是相同的,那么您当然可以从实例变量中提取它们,并且只传递给getcached(),这些值根据每个属性的不同而有所不同。

    底线 :如果有方法提取 逻辑 你在一个基本方法中所做的,这样使用这个逻辑就变成了一个一行程序,那么这可能是最好的方法,因为当你有特殊情况时,它更容易重写。如果你做不到这一点,代码生成可以帮你完成一些繁重的工作,但是你需要像 我什么时候再出生 , 如何重新生成 等。

        2
  •  1
  •   TLiebe    14 年前

    退房 CodeSmith . 他们有免费试用版,如果你想买的话,价格也不贵。我用过它,它非常适合基于数据库生成代码(我猜你就是这么做的)。模板设置完成后,可以随时重新生成代码。您可以让它从数据库架构中读取属性名,也可以输入要使用的值。我相信如果你想一次生成一整批类,你甚至可以让它从文件中读取值。

        3
  •  1
  •   Johannes Rudolph    14 年前

    您可以使用T4模板签出。我不太确定哪个是t4的“资源”,但我发现 article 在visualstudiomagazine上。

    它是免费的,有一个易于使用的语法,实际上被许多项目(例如亚音速)用于代码生成,所以您应该能够找到一些真实的场景。