我正在尝试设计3层应用程序:
1)数据访问层
2)业务层
3)用户界面
我尝试将类解耦,以便在业务层上为数据访问类创建接口,如下所示:
public interface ICountryRepository:IRepository
{
Country GetCountry(int ID);
int CreateCountry(Country obj);
Boolean UpdateCountry(Country obj);
Boolean DeleteCountry(Country obj);
...
...
}
我将接口作为param传递给服务构造函数:
public CountryService(ICountryRepository repository,ILanguageRepository lang_repository)
{
....
}
但是在CountryService上我需要加载当前用户及其权限,以便我可以检查是否可以应用该操作:
public Country GetCountry(int ID)
{
if securityService.UserHasPermission(currentUser, GetPermission("CanGetCountry"))
{
return repository.GetCountry(ID);
}
else
{
Throw(New SecurityException("No permissions for that operation ...."))
}
}
这意味着我必须实例化SecurityDataAccess对象并将其传递给我的业务层程序集上的SecurityService的构造函数,我试图避免将对象分离。现在我甚至没有在业务程序集上引用任何DataAccess程序集。
我在考虑在这里使用IoC容器。使用外部配置我可以从配置文件中获取正确的类/程序集。但我不确定这是否是正确的解决方案,因为据说IoC容器应该在一个地方使用以保持简单,并且它应该是大多数时间的顶级程序集(UI程序集)。
有人建议解决这个问题吗?
答案 0 :(得分:1)
为什么不将安全服务添加到Country服务的构造函数中?这样,IOC容器可以解决依赖关系,并在需要时注入安全性。这意味着IOC Container将负责构建您的CountryService对象。并且您将使用容器来获取所有服务。
另一种选择可能是对您的存储库进行“规范化”......
将其修剪为只有4-5个基本功能,对于所有存储库都是相同的,然后使用泛型使它们看起来都相似,所以没有
UpdateCountry(...) 但 更新(T对象)
这样的事情: http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx
然后,您可以使用可复制链模式将安全代码放在数据库代码之前(http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern)
因此,您可以拥有一个验证访问权限的SecurityChecker,如果无效则抛出异常,或者在链中的下一个链接中传递请求(您也可以通过这种方式动态添加日志,或者计时或其他)
答案 1 :(得分:0)
您是否需要在数据访问层中实施安全性?如果您将安全服务移动到业务层,Heiko建议。换句话说,在业务层中执行安全性并完全避免IoC问题。
答案 2 :(得分:0)
这可能是一个离线的,如果它是道歉,我是一个潜伏的Java EE程序员。在我看来,在基础设施中,声明性地更好地解决了授权方法。
这个article似乎表明.Net与Java EE一样,提供了一种以声明方式控制访问的工具。这种方法对你有用吗?