我们有一个服务公开客户端使用的所有数据,所有对象都有接口IAuthorized
。
需要根据用户凭据过滤到客户端的数据。
流程就像客户端调用服务一样 - >该服务调用从数据库中获取数据的SomeManager类......
这里是AuthorizationManager来过滤数据......
public class SomeManager
{
public object[] Foo()
{
var data = Repository.GetData();
return autorizationManager.Filter(data);
}
public object[] Foo_Else()
{
var data = Repository.GetOtherData();
return autorizationManager.Filter(data);
}
}
你可以看到每个方法都需要过滤,
所以我问你的是:我们可以构建一个基类,用输出数据的某些属性过滤每个方法吗?这很聪明吗? 我们应该这样离开吗?简单的wach方法我们shell调用autorization?
你能想出更好的方法吗?有些事情是这样的:
public class EngineManager :BaseFilterAutho
{
[AuthorizationCollection]
public object[] Foo()
{
var data = Dao.GetData();
return data; //get filtered
}
[SingleCollection]
public object Foo_Else()
{
var data = Dao.GetOtherData().First();
return data //get filtered
}
}
答案 0 :(得分:1)
我参与了一个项目,其中数据是通过用户的授权进行过滤的。使用的方法类似于“AuthorizationManager”方法。这需要编写大量的过滤代码,但它工作正常且易于理解。
还有其他方法,您的想法当然可以实施。你所指的是使用面向方面编程,AOP。这是Java世界中的常见方式,也可以在.Net中使用。 PostSharp是一个使这成为可能的第三方库。我自己从未在一个工作项目中使用过PostSharp,但我现在正在玩它以自己学习AOP。
下面是使用PostSharp实现的一个方面的示例,它将改变方法的返回值以过滤返回的数据。这是一个虚拟的方面,我正在玩PostSharp demo,过滤返回的数据只返回包含字母“S”的那些联系人。
如您所见,此方面要求返回值为IQueryable。我怀疑你总是需要对返回值的数据类型有一些基本的了解,例如:如果你正在使用IQueryable,ICollection,数组或其他东西。
[Serializable]
public class CollectionFilterAspect : OnMethodBoundaryAspect
{
public override void OnExit(MethodExecutionArgs args)
{
base.OnExit(args);
IQueryable<Contact> retVal = (IQueryable<Contact>)args.ReturnValue;
args.ReturnValue = from r in retVal where r.LastName.Contains("S") select r;
}
}
要使用此方面,您可以使用建议的语法,在方法上放置一个属性以指示应该对其进行过滤。
[CollectionFilterAspect]
public IQueryable<Contact> GetByName(string value)
虽然这个简短的演示说明这肯定是可能的,但它可能是也可能不是一个好主意。我没有在现实世界的软件中使用它的经验,所以我无法帮助你。