因此,我正在考虑将我的业务操作(或者更确切地说是它们的名称)放在数据库中,这样我就可以将它们链接到用户角色(用于授权),并在操作上设置一个通知系统。
主要问题是如何将操作(可能由字符串表示,如"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方法引用传递到授权方法中(不同的操作将具有不同的方法签名)。然后,授权方法必须使用反射来查找BusinessOpAttribute并获取操作的字符串名称(它在数据库中的表示方式)。
我想我可以做的另一件事是创建一系列表示操作字符串名称的常量,并将它们用于授权方法,但在执行操作时只调用业务方法。但是,我仍然没有一个项目(无论是方法还是字符串)来代表所有各方的业务操作。
有没有人有这方面的经验,也许还有另一种我没有考虑过的选择?
答案
最终通过评论和接受的答案来决定。我会为每一项业务做一节课。就像这样:
[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
}
}发布于 2012-01-01 01:23:12
我们处理类似问题的方法是让实际操作表示指定类上的具体方法。最大的问题是params,我们总是把它留给实现方法来处理。
所以在你的例子中,我会重构类似于:
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;注意,我将外观更改为CustomerFacade,在此CustomerFacade中,GetCustomerById将更改为View。这只是解决这个问题的一种方法。
例如,您还可以将所有内容保存在单个外观中,并将方法名更改为CustomerView。另外,如果存在依赖于现有外观名称的其他代码段,则可以更改操作名或添加重定向方法,将请求重定向到正确的基础facade方法。
这可能需要根据您的实现进行一些调整,但它应该给您一个大致的想法。
这种方法的好处是,您不必每次想要实现新操作时都更新此方法。
https://stackoverflow.com/questions/8691370
复制相似问题