sam*_*sam 6 c# dsl lambda closures action
我正在努力编写我的第一个DSL用于工作中的简单工具.我正在使用构建器模式来设置复杂的父对象,但是我遇到了砖墙,用于构建父对象的子集合.这是一个示例:
使用:
var myMorningCoffee = Coffee.Make.WithCream().WithOuncesToServe(16);
Run Code Online (Sandbox Code Playgroud)
关闭样本(我认为这就是他们所谓的):
var myMorningCoffee = Coffee.Make.WithCream().PourIn(
x => {
x.ShotOfExpresso.AtTemperature(100);
x.ShotOfExpresso.AtTemperature(100).OfPremiumType();
}
).WithOuncesToServe(16);
Run Code Online (Sandbox Code Playgroud)
示例类(没有子PourIn()方法,因为这是我想要弄清楚的.)
public class Coffee
{
private bool _cream;
public Coffee Make { get new Coffee(); }
public Coffee WithCream()
{
_cream = true;
return this;
}
public Coffee WithOuncesToServe(int ounces)
{
_ounces = ounces;
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
所以在我的应用程序工作中,我有复杂的对象构建很好,但我不能为我的生活弄清楚如何获取父对象上的子集合编码的lambda.(在这个例子中,它是expresso的镜头(儿童收藏)).
也许我在这里混淆概念而且我不介意被直接设置; 但是,我真的很喜欢这个如何阅读,并想知道如何使这个工作.
谢谢,山姆
好的,我想出了如何使用附加表达式生成器来编写 DSL。这就是我希望 DSL 的读取方式:
var myPreferredCoffeeFromStarbucks =
Coffee.Make.WithCream().PourIn(
x =>
{
x.ShotOfExpresso().AtTemperature(100);
x.ShotOfExpresso().AtTemperature(100).OfPremiumType();
}
).ACupSizeInOunces(16);
Run Code Online (Sandbox Code Playgroud)
这是我通过的测试:
[TestFixture]
public class CoffeeTests
{
[Test]
public void Can_Create_A_Caramel_Macchiato()
{
var myPreferredCoffeeFromStarbucks =
Coffee.Make.WithCream().PourIn(
x =>
{
x.ShotOfExpresso().AtTemperature(100);
x.ShotOfExpresso().AtTemperature(100).OfPremiumType();
}
).ACupSizeInOunces(16);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Count == 2);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Dequeue().IsOfPremiumType == true);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Dequeue().IsOfPremiumType == false);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.CupSizeInOunces.Equals(16));
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的 CoffeeExpressionBuilder DSL 类:
public class Coffee
{
public List<ExpressoExpressionBuilder> expressoExpressions { get; private set; }
public bool HasCream { get; private set; }
public int CupSizeInOunces { get; private set; }
public static Coffee Make
{
get
{
var coffee = new Coffee
{
expressoExpressions = new List<ExpressoExpressionBuilder>()
};
return coffee;
}
}
public Coffee WithCream()
{
HasCream = true;
return this;
}
public Coffee ACupSizeInOunces(int ounces)
{
CupSizeInOunces = ounces;
return this;
}
public Coffee PourIn(Action<ExpressoExpressionBuilder> action)
{
var expression = new ExpressoExpressionBuilder();
action.Invoke(expression);
expressoExpressions.Add(expression);
return this;
}
}
public class ExpressoExpressionBuilder
{
public readonly Queue<ExpressoExpression> ExpressoShots =
new Queue<ExpressoExpression>();
public ExpressoExpressionBuilder ShotOfExpresso()
{
var shot = new ExpressoExpression();
ExpressoShots.Enqueue(shot);
return this;
}
public ExpressoExpressionBuilder AtTemperature(int temp)
{
var recentlyAddedShot = ExpressoShots.Peek();
recentlyAddedShot.Temperature = temp;
return this;
}
public ExpressoExpressionBuilder OfPremiumType()
{
var recentlyAddedShot = ExpressoShots.Peek();
recentlyAddedShot.IsOfPremiumType = true;
return this;
}
}
public class ExpressoExpression
{
public int Temperature { get; set; }
public bool IsOfPremiumType { get; set; }
public ExpressoExpression()
{
Temperature = 0;
IsOfPremiumType = false;
}
}
Run Code Online (Sandbox Code Playgroud)
欢迎任何和所有建议。
| 归档时间: |
|
| 查看次数: |
2291 次 |
| 最近记录: |