我需要在应用程序中启用后期绑定,并且希望有一个使用JSON配置文件显式配置服务的选项。
我有一个接口IDependency
和两个类DependencyOne
和DependencyTwo
都实现了该接口。我还有一个SomeService
类,该类具有带有以下签名的构造函数:
public SomeService(IDependency dependency1, IDependency dependency2)
我想为DependencyOne
注入dependency1
,为DependencyTwo
注入dependency2
。
如何在不使用代码中任何属性的情况下仅以JSON配置进行配置?有可能吗?
需要无属性要求,因为后期绑定程序集不应该依赖于AutoFac。
谢谢。
更新:解决方案
Travis在下面的回答包含指向FAQ的链接,该链接使我找到了可接受的解决方案。使用“标记”界面,例如IDependencyOne : IDependency
和IDependencyTwo : IDependency
,然后SomeService(IDependencyOne dependency1, IDependencyTwo dependency2)
。我不太喜欢的是,现在IDependency
的通用修饰符需要实现所有标记,如果要在LoggingDecorator : IDependencyOne, IDependencyTwo
中使用它,请说SomeService
,但是只要标记保持空白,这不是什么大问题。这样,我不必在后期绑定程序集中强制依赖于Autofac的dll,而仍然可以在JSON文件中配置DI。
答案 0 :(得分:0)
如果同一接口有两种不同的实现方式,不能一视同仁,那就是代码的味道。 There is an FAQ about ways to work around that,但简单的答案是如果没有一些人工操作,您将无法从字面上指定相同接口的两个不同实例。没有一种机制可以轻松地对此进行连接因为这是一个设计问题。
请花些时间阅读the FAQ,以了解为什么以及除我在此显示的内容以外的其他解决方法。
但是,假设您不能更改界面IDependency
,因为通常这是人们的症结所在。我们还要假设,出于某种原因,您不能仅将DependencyOne
和DependencyTwo
放在构造函数中。 (这两个都是我希望解决此问题的第一位,而不是试图使我的DI接线复杂化,但是再次,让我们说一下,这不是一个选择。)
我可能会使用元数据密钥在配置中注册每个实例,以便以后使用。
{
"components": [{
"type": "MyAssembly.DependencyOne, MyAssembly",
"services": [{
"type": "MyAssembly.IDependency, MyAssembly"
}],
"metadata": [{
"key": "type",
"value": "One",
"type": "System.String, mscorlib"
}]
}, {
"type": "MyAssembly.DependencyTwo, MyAssembly",
"services": [{
"type": "MyAssembly.IDependency, MyAssembly"
}],
"metadata": [{
"key": "type",
"value": "Two",
"type": "System.String, mscorlib"
}]
}]
}
好的,因此我们有两个组件,每个组件都公开相同的接口,并且每个组件分别具有One
或Two
的元数据键。
In your class you can use that metadata.
public class SomeService
{
readonly IEnumerable<Meta<IDependency>> _dependencies;
public SomeService(IEnumerable<Meta<IDependency>> dependencies)
{
_dependencies = dependencies;
}
public void DoSomething(string parameter)
{
var dep = _dependencies.First(a => a.Metadata["type"].Equals(parameter));
dep.DoSomething();
}
}
想法是您可以使用元数据选择适当的内容。显然可以根据自己的需要进行调整;也许这不是调用者的参数,而是其他地方的代码;这个概念仍然成立。
不过,我仍然不能强烈建议您check out the FAQ和强烈考虑进行重新设计,以完全避免这种情况。从长远来看,它将使您的生活和其他开发人员的生活更加轻松。