这是一个代码设计问题:)
我有一个DelegatingHandler,它接受http请求标头并验证API密钥。我猜是很常见的任务。在我的控制器中,我调用我的业务逻辑并传递所有与业务相关的信息。但是现在我面临着根据某些api-key改变业务逻辑内部行为(单独的程序集)的任务的挑战。
我想到了各种可能的解决方案......
更改业务逻辑方法签名以请求api-key。
public void SomeUseCase(Entity1 e1,Entity2 e2,string apiKey);
使用HttpContext.Current访问当前请求上下文。但是,我在某处读到使用HttpContext将我的托管选项限制为IIS。那有更好的选择吗?
var request = HttpContext.Current.Request; //下一个提取标题信息
使用会话(真的不想走那条路......)
您对该主题有何看法?
我会选择#1虽然我不喜欢在业务逻辑方法中混合使用enivonmental的想法。但是根据你的观点,你可能会认为api-key实际上与逻辑相关。
更新#1: 我正在使用delegatingHandler验证apiKey,一旦验证,我将它添加到Request的Properties Collection。
有问题的部分是如何将“api-key”或RegisteredIdentifier传递给业务逻辑层。现在我将对象(例如IRegisteredIdentifier)作为参数传递给业务逻辑类的构造函数。我知道没有更优雅的方法来解决这个问题(?)。我想改变方法签名,但我不确定它是否是界面污染。有些方法需要使用api-key,大多数方法都不需要。经验告诉我,这个数字更有可能增长而不是下降:)所以在我的bl课程中保持对它的引用似乎是一个不错的选择。
感谢您的回答 - 我认为所有这些都是我解决方案的一部分。我是StackOverflow的新手..但据我所知 - 我还不能评价答案。请放心,我仍然感激不尽:)
答案 0 :(得分:1)
我建议两种不同的选择。
将值提升为自定义HTTP标头(例如mycompany-api-key:XXXX)。这使您的委托处理程序更像标准HTTP中介。如果您将请求移交给某个辅助内部服务器,这将非常方便。
将api-key放入request.Properties字典中。属性字典的想法是提供放置有关请求的自定义元信息的位置。
HTTP努力确保身份验证/授权与实际请求正交关系,这就是为什么我会尝试将其保留在操作签名之外。
答案 1 :(得分:0)
我会选择选项1。 但是您可以在业务逻辑中引入实体RegisteredIdentifier(由Jim Arlow和Ila Neustadt提供的企业模式和MDA)。 api-key可以转换为RegisteredIdentifier。
RegisteredIdentifier id = new RegisteredIdentitief(api-key);
public void SomeUseCase(Entity1 e1, Entity2 e2, RegisteredIdentifier id);
答案 2 :(得分:0)
业务逻辑层依赖于API密钥。所以我建议:
interface IApiKeyProvider
{
string ApiGet { get; }
}
..然后让你的BLL要求提供一个实现该接口的对象(在构造函数,设置,甚至每个需要它的方法中)。
因为将来它可能不是一个API密钥。关键在于,这标识了BLL依赖于某些东西,并为该东西定义了契约。
真实世界的例子:
然后,在您的DI容器(Ninject等)中,将您自己的ConfigFileApiKeyProvider(或其他)实现绑定到该接口,在具有API密钥的“place”(层)中。因此,调用BLL的应用程序指定/配置API密钥的指定方式。
编辑:我误解了关于这是“如何通过HTTP做”问题的部分,而不是代码架构/代码设计问题。所以: