Jus*_*tin 5 c# dependency-injection interface
我们有一个多租户Web应用程序,其中每个租户运行许多页面.因此,我们的许多接口看起来像这样
interface ISprocketDeployer
{
void DeploySprocket(int tenantId);
}
Run Code Online (Sandbox Code Playgroud)
在我看来,将这些接口简化为不知道的可能更好tenantId
.那些页面也会不知道tenantId
,就像这样
[Inject] // Ninject
public ISprocketDeployer SprocketDeployer { get; set; }
private void _button_OnClick(object sender, EventArgs e)
{
SprocketDeployer.DeploySprocket();
}
Run Code Online (Sandbox Code Playgroud)
然后,依赖注入框架将通过查看当前经过身份验证的用户将租户ID注入为依赖项.这是一个好主意还是滥用依赖注入?
我进一步想到,许多实现也只是为了查找有关租户的详细信息而采取额外的依赖关系,并且我可以通过直接注入该详细信息来进一步减少依赖关系的数量,例如
class SprocketDeployer
{
public SprocketDeployer(ITenantRepository tenantRepository)
{
_tenantRepository = tenantRepository;
}
void DeploySprocket(int tenantId)
{
var tenantName = _tenantRepository.GetTenant(tenantId).Name;
// Do stuff with tenantName
}
}
Run Code Online (Sandbox Code Playgroud)
会成为
class SprocketDeployer
{
public SprocketDeployer(Tenant tenant)
{
_tenant = tenant;
}
void DeploySprocket()
{
var tenantName = _tenant.Name;
// Do stuff with tenantName
}
}
Run Code Online (Sandbox Code Playgroud)
然后我意识到我还可以以相同的方式注入其他"依赖项",例如有关当前登录用户的详细信息.
那时我变得不确定了.虽然一开始看起来好像很神奇,但我意识到我不确定何时停止添加额外的"依赖".我如何确定应该是什么依赖项以及什么应该是参数?
我不会称之为虐待,但这就是说:
依赖注入(通过容器)的一般用例是注入不直接表示状态的纯服务。迫在眉睫的问题之一是通知容器应在运行时注入对象的哪个实例。如果您的 SprocketDeployer 需要租户,并且您的系统包含许多租户,那么容器如何确定哪个租户在运行时提供
如果您想避免传递租户,请考虑使用线程本地存储 (TLS)。但是,管道中仍然存在需要将租户添加到 TLS 的时刻。
编辑
从你的评论来看:
我通过将类型绑定到检查 HttpContext.Current 的方法并使用 InRequestScope 解决了确定在 Ninject 中运行时提供哪个租户的问题。它工作得很好,但我没有看到任何表明这是(或不是)推荐的做法。
如果我没理解错的话,这听起来像是一家工厂?如果是这样的话,我认为没有什么问题。
一个小问题可能是:不必担心服务范围如何,这很好。当它们是真正的无状态服务时,您可以将它们视为纯粹的可交换组件,不会根据容器配置产生任何副作用。