zoukankan      html  css  js  c++  java
  • dsl boo3个例子 9

    ƒ The Message-Routing DSL is an example of an imperative DSL. It’s executed to

    perform some goals.

    ƒ The Authorization DSL is a more declarative example (but still mostly impera-

    tive). It’s executed to produce a value, which is later used.

    ƒ The Quote-Generation DSL is a mostly declarative example. It produces an

    object graph that’s later taken up by the processing engine.

    Message-Routing DSL

    The main reason that we want to use a DSL here is to keep the system flexible and

    make it easy to add new messages and transformations. This DSL will be used by tech-

    nical people, most probably the developers on the project. This, in turn, means that

    we can use a technical DSL here. Each script using this DSL will probably have the fol-

    lowing responsibilities:

    ƒDeciding whether the script can handle the message

    ƒTransforming the message to the internal message representation

    ƒDeciding where to dispatch the message

    clip_image001

    RouteNewOrder.boo DSL定义

    # decide if this message match this DSL script

    return if msg.type != "NewOrder" and msg.version == "1.0"

    # decide which handle is going to handle it

    HandleWithNewOrderHandler:

    # define a new list

    lines = []

    # add order lines to the list

    for line in msg.order_lines:

    lines.Add(OrderLine( line.product, line.qty ) )

    # create internal message representation

    returnNewOrderMessage(

    msg.customer_id,

    msg.type,

    lines.ToArray(OrderLine) )

    clip_image003

    IQuackFu it allows us to handle unknown method calls at runtime in asmart fashion.

    RoutingBaseThe Message-Routing DSL script will be compiled into a class thatinherits from RoutingBase, and all the code in the script
     will go into the Route()method, while the  msg field will contain the current message during execution
    RoutingDslEnginecompile this DSL. We do it using a DSL engine
    RouterThe Routerclass hook it up to the Routerclass

    使用:

    // translate from the post body to a json object
    byte[] bytes = context.Request.BinaryRead(context.Request.TotalBytes);
    string json = Encoding.UTF8.GetString(bytes);
    JsonSerializer jsonSerializer = new JsonSerializer();
    JsonReader reader = new JsonReader(new StringReader(json)); JavaScriptObject javaScriptObject = (JavaScriptObject)jsonSerializer.Deserialize(reader);

    // send the json object to be routed
    string scriptsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin");
    string returnMessage = Router.Route(scriptsPath,
    new JsonMessageAdapter(javaScriptObject));
    context.Response.Write(returnMessage);

    context.Response.Write(returnMessage);

    JsonMessageAdapter class is responsible for translating the JavaScriptObject into an IQuackFu, which is what we expect in the MessageRouting DSL

    using Boo.Lang;
    using Newtonsoft.Json;
    public class JsonMessageAdapter : IQuackFu
    {
    private readonly JavaScriptObject js;
    public JsonMessageAdapter(JavaScriptObject js)
        {
    this.js = js;
        }
    public object QuackGet(string name, object[] parameters)
        {
    object value = js[name];
    JavaScriptArray array = value as JavaScriptArray;
    if(array!=null)
            {
    return array.ConvertAll(delegate(object obj)
                {
    return new JsonMessageAdapter((JavaScriptObject) obj);
                });
            }
    return value;
        }

     
     

    Authorization DSL

    clip_image005

    ƒThe CheckAuthorization() method and the Operation property are both

    abstract, so derived classes (and our DSL) have to implement them.

    ƒThe Allow() and Deny() methods are the only ways for the derived class to

    affect the state of the rule. Both methods accept a reason string, which means

    that we’re automatically documenting the reason for the decision.

    operation "/account/login"

    if Principal.IsInRole("Administrators"):
            Allow("Administrators can always log in")
            return

    if date.Now.Hour < 9 or date.Now.Hour > 17:
            Deny("Cannot log in outside of business hours, 09:00 - 17:00")

    e make use of the Boo date keyword

    to reference System.DateTime, which we haven’t seen before, but that isn’t very

    interesting.

    There is one interesting thing here: the first line isn’t something that we’ve seen so

    far. We know that we need to provide an implementation of the Operation property,

    but how can we do it?

    It’s done using a macro, which takes the first argument of the macro, generates a

    property, and returns that argument from the property.

    使用

     WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
    bool? allowed = Authorization.IsAllowed(principal, "/account/login");
    Console.WriteLine("Allowed login: {0}", allowed);
    Console.WriteLine(Authorization.WhyAllowed(principal, "/account/login"));

    The Quote-Generation DSL

    clip_image007

    The first is that we use astrange naming convention for some of the methods (requires, same_machine_as,specification, and users_per_machine do not follow the standard .NET namingconvention). This is the easiest way to get keywords in the DSL.

    Note that thespecification() method accepts a delegate as the last parameter, so we’re using

    anonymous blocks again, like we did in the Message-Routing DSL Handle method.

    The second thing to note is all the @ signs scattered through the DSL (listing 4.16).

    Those are called symbols, and they translate to string literals without the annoying

    The last thing that’s worth noting about the QuoteGeneratorRule class is that itaccepts a RequirementsInformation class. This allows it to understand what context itruns in, which will be important later on.

    The QuoteGeneratorRule class is responsible for building the object model thatwill later be processed by the quote-generation engine.

    specification @vacations:
            requires @scheduling_work
            requires @external_connections
           
    specification @salary:
            users_per_machine 150
           
    specification @taxes:
            users_per_machine 50

    specification @pension:
            same_machine_as @health_insurance
  • 相关阅读:
    CSDN工具-CSDN信息查看
    Plaintext Encryption
    摆脱任何工具-简单代码让文件夹加密
    pyquery解析库
    beautifulsoup解析库
    lxml beautiful pyquery三种解析库
    python的enumerate lambda isinstance filter函数
    python字符串的split replace strip
    整理github总结
    简单python爬虫实例
  • 原文地址:https://www.cnblogs.com/2018/p/2623623.html
Copyright © 2011-2022 走看看