dsl boo3个例子 9

本文深入探讨了DSL(领域特定语言)在软件开发中的应用,包括消息路由DSL、授权DSL和报价生成DSL的功能与实现。文章详细介绍了如何通过DSL实现灵活的消息处理、权限检查和报价生成过程,以及在不同场景下的应用策略。

ƒ 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

转载于:https://www.cnblogs.com/2018/archive/2012/11/05/2623623.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值