3

C# 用の最もクールなテンプレート エンジンの 1 つであるDot Liquidを使用しようとしています。Dot Liquid は、テンプレートを安全に使用するための方法を使用します。解説ページはこちら。

wikiの説明は次のとおりです。

デフォルトでは、DotLiquid は Render メソッドへのパラメーターとして限られた数の型のみを受け入れます。これには、.NET プリミティブ型 (int、float、string など) と、IDictionary、IList、および IIndexable (カスタム DotLiquidインターフェース)。

任意の型をサポートしている場合、プロパティまたはメソッドが意図せずにテンプレートの作成者に公開される可能性があります。これを防ぐために、DotLiquid は Drop オブジェクトを使用します。ドロップは、オプトイン アプローチを使用してオブジェクト データを公開します。

Drop クラスは ILiquidizable の実装の 1 つにすぎません。オブジェクトを DotLiquid テンプレートに公開する最も簡単な方法は、ILiquidizable を直接実装することです。

ウィキのサンプル コード:

public class User
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public class UserDrop : Drop
{
    private readonly User _user;

    public string Name
    {
        get { return _user.Name; }
    }

    public UserDrop(User user)
    {
        _user = user;
    }
}

Template template = Template.Parse("Name: {{ user.name }}; Email: {{ user.email }};");
string result = template.Render(Hash.FromAnonymousObject(new
{
    user = new UserDrop(new User
    {
        Name = "Tim",
        Email = "me@mydomain.com"
    })
}));

したがって、DataRow を Liquid に渡すと、Liquid はその内容を表示させず、次のように伝えます。

'System.Data.DataRow' は組み込み型でも ILiquidizable を実装していないため、無効です

ILiquidizable も実装する DataRow オブジェクトを渡すソリューションはありますか? ありがとう

4

1 に答える 1

5

marc_s が示したように、DataRowオブジェクトを独自のクラス インスタンスに変換するか、少なくとも独自のクラス インスタンスでラップする必要があります。次のようにラップすることをお勧めします。

internal class DataRowDrop : Drop
{
    private readonly DataRow _dataRow;

    public DataRowDrop(DataRow dataRow)
    {
        _dataRow = dataRow;    
    }

    public override object BeforeMethod(string method)
    {
        if (_dataRow.Table.Columns.Contains(method))
            return _dataRow[method];
        return null;
    }
}

サンプルの使用法は次のとおりです。

[Test]
public void TestDataRowDrop()
{
    DataTable dataTable = new DataTable();
    dataTable.Columns.Add("Column1");
    dataTable.Columns.Add("Column2");

    DataRow dataRow = dataTable.NewRow();
    dataRow["Column1"] = "Hello";
    dataRow["Column2"] = "World";

    Template tpl = Template.Parse(" {{ row.column1 }} ");
    Assert.AreEqual(" Hello ", tpl.Render(Hash.FromAnonymousObject(new
    {
        row = new DataRowDrop(dataRow)
    })));
}

また、このドロップ クラスの例と、対応する単体テストを DotLiquid ドロップの単体テストに追加しました。

于 2010-12-13T18:39:58.343 に答える