要创建我们的测试数据,我们使用Builder模式的以下变体(简化示例!):
示例类:
public class Person
{
public string Name { get; set; }
public string Country { get; set; }
}
建设者:
public class PersonBuilder
{
private string name;
private string country;
public PersonBuilder()
{
SetDefaultValues();
}
private void SetDefaultValues()
{
name = "TODO";
country = "TODO";
}
public Person Build()
{
return new Person
{
Name = name,
Country = country
};
}
public PersonBuilder WithName(string name)
{
this.name = name;
return this;
}
public PersonBuilder WithCountry(string country)
{
this.country = country;
return this;
}
}
注意:示例本身的上下文不相关。这里重要的是如何在示例中,像PersonBuilder这样的构建器类可以通过查看实体类(Person)并应用相同的模式来完全生成 - 见下文。
现在假设person类有15个属性而不是2个。实现构建器类需要一些猴子工作,而理论上,它可以自动从Person类生成。我们可以使用代码生成来快速设置构建器类,并在以后需要时添加自定义代码。
代码生成过程必须知道上下文(人类的名称和属性),因此简单的基于文本的代码生成或正则表达式魔法在这里感觉不对。首选的是动态解决方案,而不是基于文本的解决方案,并且可以从视觉工作室内快速触发。
我正在寻找为此类场景执行代码生成的最佳方法。 反射? CodeSmith中? T4模板? Resharper Live模板与宏?
我期待看到一些很棒的答案:)
答案 0 :(得分:2)
T4解决方案是一个很好的Visual Studio集成选项。您可以在T4模板中使用反射来实际生成代码。
答案 1 :(得分:2)
我们在CodeSmith Generator 5.x中添加了一项功能,允许您生成现有代码。请看一下documentation here。您还可以在CodeSmith Generator模板中使用反射或任何.NET库。
由于 -Blake Niemyjski
答案 2 :(得分:0)
如果仅用于测试,请考虑像RhinoMocks这样的模拟框架:
internal class PersonBuilder
{
private MockRepository _mockRepository;
private IPerson _person;
public PersonBuilder()
{
_mockRepository = new MockRepository();
_person = _mockRepository.Stub<IPerson>();
}
public PersonBuilder WithName(string name)
{
_person.Name = name;
return this;
}
public PersonBuilder WithCountry(string Country)
{
_person.Country= Country;
return this;
}
public IPerson Build()
{
_mockRepository.ReplayAll();
return _person;
}
}
通过这种方式,您的建筑师可以随着您的需求而发展。此外,您无需更改Build方法。只需添加“WithX”方法即可。
答案 3 :(得分:0)
查看ABSE建模方法及其IDE AtomWeaver。 ABSE是一个基于模板的建模和代码生成框架,其中通过应用“构建块”(Atoms)创建模型(与UML或MDA无关)。这些Atom是模板/程序混合并且是上下文感知的:Atom可以根据它在树上的位置以及某些Atom的存在/不存在来生成代码。
模型主机(在本例中为AtomWeaver)将“执行”模型以获取所需的源代码。模型可以是“源”:根据需要更改模型并重新生成。
AtomWeaver没有集成到Visual Studio中,但可以毫无问题地与它一起工作。