设计流畅建设者C#创建对象图 [英] Designing fluent builders to create an object graph in C#

查看:225
本文介绍了设计流畅建设者C#创建对象图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在在C#写流利的建设者,所以我可以简化创建对象图的逻辑的第一次尝试。

I am making a first attempt at writing fluent builders in C# so I can simplify the logic for creating object graphs.

我首先想到的是要建立一个流畅的建设者为每个类,那么其嵌套层次是这样的:

My first thought was to create a fluent builder for each class, then nest them hierarchically like this:

School school = SchoolBuilder.New()
  .WithName("Whatchamatta U")
  .AddClass(
      ClassBuilder.New()
      .WithName("Arithmetic")
      .WithClassNumber("101")
      .AddStudent(
         StudentBuilder.New()
         .WithName("John Smith")
      )
      .AddStudent(
         StudentBuilder.New()
         .WithName("Jane Smith")
      )
  )
  .Save()

这是简单的使用C#接口,一个状态机实现,且相当容易理解,无论是作为一个开发人员尝试读取代码和开发人员试图创建新的代码(随着*=设置属性,添加*=添加子对象,保存做任何需要做的事情,以创建图形),但我想这可能是更容易为开发商读写一个DSL看起来是这样的:

This is straightforward to implement as a state machine using C# interfaces, and fairly easy to understand, both as a developer trying to read the code AND as a developer trying to create new code ("With*"=set a property, "Add*"=add a child object, "Save" does whatever needs to be done to create the graph), but I thought it might be easier for a developer to read and write a DSL that looks something like this:

School school = SchoolBuilder.New()
  .WithName("Whatchamatta U")
  .AddClass()
    .WithClassName("Arithmetic")
    .WithClassNumber("101")
    .AddStudent()
       .WithStudentName("John Smith")
    .AddStudent()
       .WithStudentName("Jane Smith")         
  .Save()

由于对消息建设者正在经历最顶层的父生成器对象,我想我需要找到某种方式来路由下来的层次结构合适的子生成器对象。在Ruby中这可以用method_missing的做,但我看不出在C#中实现这样的一个聪明的办法。

Since the messages for all builders are going through the topmost parent builder object, I think I need to find some way to route them down the hierarchy to the appropriate child builder object. In Ruby this can be done with method_missing, but I can't see an smart way to implement this in C#.

这是丑陋的解决办法是让每个父母落实每一个潜在的后代对象的接口,其中每个方法的路线它的调用给孩子。显然,这是不可取的,尤其是当我添加更多的制造商类层次,但我不知道,以虚拟实现这些接口在编译时简洁的方式,但拦截到该接口和代理下来树中的所有通话,点菜method_missing的。我可以看到有动态实现使用动态代理在C#在运行时的接口方式,但我不认为任何这些将支持智能感知。

An ugly solution would be to have each parent implement the interface of every potential descendent object, where each method routes its invocation to the child. Obviously this is not desirable, especially as I add more builder classes to the hierarchy, but I don't know of a concise way to "virtually" implement these interfaces at compile time but intercept all calls to that interface and proxy them down the tree, à la method_missing. I can see that there are ways to dynamically implement interfaces at runtime in C# using a dynamic proxy but I don't think any of these will support intellisense.

我的要求一个),这适用于智能感知和b)任何制造商可以用来构建对象不参照其母公司---这意味着我希望所有的建设者们能够处理其子建设者的建设(意思是丑陋的解决方案会是的真正的丑陋)

My requirements are that a) this works with intellisense and b) any builder can be used to build objects without reference to its parent---meaning I want all builders to be able to handle the construction of its child-builders (meaning the the ugly solution would be really ugly)

有没有办法拿在C#这第二条路呢? ?或者这是错误的方式去思考它。

Is there a way to take this second route in C#? Or is this the wrong way to think about it?

推荐答案

另一种可能是使用的对象初始化语法来代替。因此,像:

An alternative might be to use the object initializer syntax instead. So something like:

School school = new School {
    Name = "Watchamatta U",
    Classes = new[] {
        new Class {
            Name = "Arithmetic",
            Number = "101",
            Students = new[] {
                // etc.
            }
        }
    }
};

这初始化属性,所以你可以改变阵列为对象。

This initializes properties, so you can change the arrays into objects.

这篇关于设计流畅建设者C#创建对象图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆