业务操作建模:将名称链接到代码

本文关键字:链接 代码 操作 建模 业务 | 更新日期: 2023-09-27 18:19:13

因此,我正在考虑将我的业务操作(或者更确切地说,它们的名称)放在数据库中,以便我可以将它们链接到用户角色(用于授权),并在操作上设置通知系统。

问题的主要点是如何转换操作(可能由字符串表示,如"Customer")。New"或"Customer.View")从数据库导入到系统中运行的代码中。我想出的大多数方法似乎都很笨拙。

示例1 -处理所有操作的通用方法

public static object RunOperation(string Op, string User, params object[] Parms)
{
    switch(Op)
    {
        case "Customer.View":
            return BLL.Facade.GetCustomerById((int)Parms[0]);
            break;
        case "Customer.New":
            return BLL.Facade.CreateCustomer(Parms[0] as Customer);
            break;
        ...
    }
}

我最讨厌的是选角。但是授权是很容易的。Authorize(Op, User);

还有一种方法:

[BusinessOp("Customer.New")]
public static int CreateCustomer(Customer NewCustomer)
{
    ...
}

但是授权有点不稳定,因为我假设我必须将CreateCustomer方法引用传递给Authorize方法(并且不同的操作将具有不同的方法签名)。然后,Authorize方法必须使用反射来查找BusinessOpAttribute并获得操作的字符串名称(它在数据库中表示的方式)。

我想我可以做的另一件事是创建一系列表示操作的字符串名称的常量,并将它们用于Authorize方法,但是在执行操作时只调用业务方法。但是,我仍然没有一个项目(无论是方法还是字符串)向所有各方表示业务操作。

有没有人有过这样的经验,有没有我没有考虑过的其他选择?

最终决定通过评论与接受的答案。我将为每个业务操作创建一个类。像这样:

[BusinessOperation]
public static class CustomerNew
{
    public const string Key = "Customer.New";
    public static bool Authorize(string UserName) // or perhaps IPrincipal User
    {
        // Authorize method will use key to check against database
        ...
    }
    public static int Invoke(Customer NewCustomer)
    {
        // Invoke method has well-defined parameters
        ...
        // Can also use key to notify listeners of operation completion
    }
}

业务操作建模:将名称链接到代码

处理类似问题的方法是让实际操作表示指定类的具体方法。这里最大的问题是参数,我们总是把它留给实现方法来处理。

所以在你的情况下,我会像这样重构:

var asValues = Op.Split('.');
switch(asValues[0].ToLower())
{
    case "customer":
        Type type = typeof(BLL.CustomerFacade);
        System.Reflection.MethodInfo method = type.GetMethod(asValues[1], System.Reflection.BindingFlags.IgnoreCase);
        if (method != null)
        {
            return method.Invoke(BLL.CustomerFacade, Parms);
        }
        break;

注意,我将Facade更改为CustomerFacade,并且在这个CustomerFacade中,GetCustomerById将更改为View。这只是一种方法。

您还可以将所有内容保持在单个facade中,并将方法名称更改为CustomerView。同样,如果有其他代码片段依赖于现有的facade名称,您可以更改操作名称或添加重定向方法,将请求重定向到正确的底层facade方法。

这可能需要根据你的实现进行一些调整,但它应该给你一个大致的想法。

这种方法的好处是,您不必在每次要实现新操作时都更新此方法。