此方案的最佳设计是什么?
我有不同的对象类型:User
,Channel
,MessageBox
,UserGroup
等。
User
和Channel
可以拥有其他对象的权限。例如,User
将以下枚举定义为MessageBox
的权限:
CanRead,
CanWrite,
CanDelete,
...
其他枚举是为User
定义的,作为其他对象类型的所有者。
此外,Channel
在这些对象上具有不同的枚举值。例如,将Channel
视为所有者,将MessageBox
视为对象:
CanDispath
CanRetrieve
...
使用按位比较从数据库中的特定表保存和检索所有权限:
OwnerID........OwnerType........ObjectID........ObjectType........AccessLevel
1 User 10 MessageBox 38
5 Channel 12 MessageBox 18
现在在代码背后,实现权限类的最佳方法是什么?
1-将PermissionManager
,UserPermissionManager
,ChannelPermissionManager
类彼此分开定义。其他课程只需拨打PermissionManager
,如:
if (new PermissionManager.HasAccess(CurrentUser,
CurrentMessageBox,
UserPermissions.CanReadMessages))
然后PermissionManager
根据OwnerType
(UserPermissionManager
或ChannelPermissionManager
)决定与其相关的类,并调用其HasAccess
方法。这样,PermissionManager.HasAccess
总是被调用,我认为它可以使代码更易于维护和扩展。这是我的首选解决方案,但由于PermissionManager
,UserPermissionManager
和ChannelPermissionManager
引用相同的上下文,我认为应该有一个层次结构或可能是一个接口,因此这三个类变得更加集成。但我不知道如何将它们联系在一起。
2-定义IPermissionManager
界面,并从中实施UserPermissionManager
和ChannelPermissionManager
。添加PermissionManagerTypes
枚举。创建一个工厂类并调用管理器,如:
IPermissionManager UserManager =
PermissionFactory.Create(PermissionsManagerTypes.User);
if (UserManager.HasAccess(CurrentUser,
CurrentMessageBox,
UserPermissions.CanReadMessages))
这是一种将类关联在一起的失败尝试。但我觉得在这里提一下让你知道我想要实现的目标是件好事。
P.S。我不能将类定义为静态,因为它们需要具有类型为ObjectContext
的私有变量(实体框架)。
有没有更好的解决方案来实现这一目标? 感谢你和道歉,这是一个非常冗长的问题。
答案 0 :(得分:3)
嗯,这很难回答。您可以尝试创建基本接口IPermission;
interface IPermission<TOwner>
{
}
然后为希望能够拥有权限的类型实现此接口。
class UserPermission : IPermission<User>
{
public UserPermission(CustomerPermissionType type)
{
// Store the type
}
}
class ChannelPermission : IPermission<Channel>
{
public ChannelPermission (ChannelPermissionType type)
{
// Store the type
}
}
现在您需要一个为特定对象提供权限的界面。
interface IPermissionProvider
{
bool HasPermission<TOwner>(IPermission<TOwner> permission, TOwner owner, object target);
}
此时,您具有查询权限的基本功能。问题是如何管理用户和渠道权限的不同处理。你可以实现这样的东西:
class PermissionDispatcher : IPermissionProvider
{
public void RegisterPermissionProvider<TOwner>(IPermissionProvider permissionProvider)
{
// Store it somewhere
}
public IPermissionProvider GetPermissionProvider<TOwner>()
{
// Look up a permission provider that is registered for the specified type TOwner and return it.
}
bool IPermissionProvider.HasPermission<TOwner>(IPermission<TOwner> permission, TOwner owner, object target)
{
IPermissionProvider permissionProvider = GetPermissionProvider<TOwner>();
return permissionProvider .HasPermission<TOwner>(permission, owner, target);
}
}
最后一步是为用户和频道创建IPermissionProvider的特定实现,并在启动应用程序/服务时将它们注册到PermissionDispatcher。
使用方法就像这样简单:
void foo()
{
IPermissionProvider permissionProvider = ... the dispatcher, could be a singleton ...;
User user = ...;
MessageBox messageBox = ...;
UserPermission userCanReadPermission = new UserPermission(UserPermissionType.CanRead);
bool hasUserCanReadPermission = permissionProvider.HasPermission(userCanReadPermission, user, messageBox);
}
这样的事情将是解决这个问题的唯一方法,而不依赖于域类型中的权限处理。不过我绝对相信这不是完美的解决方案。
答案 1 :(得分:1)
我根本没有想到这一点,但是:
interface HasPermissions {
getPermissionsFor(object)
}
User implements HasPermissions
Channel implements HasPermissions
etc..
User user = new User();
if user.getPermissionsFor(object).contains(canRead)