虽然重新考虑项目的目的是不依赖于具体类型而是抽象它,但我已经面临这个问题,我需要添加一个项目的参考资料,我没有#39; t想要。
所以我已经勾勒出以下一段效果很好的代码:
用法:
// Old line of code that directly referenced AudioStream
// AudioStream = new AudioStream(value);
// New code that tries to find a concrete implementation of IAudioStream
var type = typeof(IAudioStream);
var implementation = TryFindImplementation<IAudioStream>();
if (implementation == null)
throw new InvalidOperationException(
"Could not find an implementation of " + type.Name);
var instance = Activator.CreateInstance(implementation, value);
AudioStream = (IAudioStream)instance;
尝试查找具体实现的方法:
private static Type TryFindImplementation<T>()
{
return (
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where typeof(T).IsAssignableFrom(type)
where type != typeof(T)
select type)
.FirstOrDefault();
}
这段代码可以被视为一种非常简单的依赖注入形式吗?
答案 0 :(得分:4)
没有。这并不简单,它非常先进。简单的方法是将AudioStream
作为参数传递给方法。
您的代码可以被视为一个简单的依赖注入框架 - 在我看来,它们已经足够了,您不需要自己编写。
答案 1 :(得分:4)
不,that's not Dependency Injection。
相反,请考虑将IAudioStream
依赖项或其工厂注入客户端代码。
public class AudioStreamClient
{
private readonly IAudioStream audioStream;
public AudiStreamClient(IAudioStream audioStream)
{
this.audioStream = audioStream;
}
public void DoStuff()
{
// use this.audioStream here...
}
}
或者,如果您每次执行IAudioStream
时都需要DoStuff
的新实例,请考虑injecting an Abstract Factory instead。
但是,请注意,这可能是 Leaky Abstraction ,而create an Adapter that manages the object's lifetime for you更好的替代方案。
答案 2 :(得分:3)
它看起来像一个有限的Service Locator实现。如果您尝试实例化的类型没有默认构造函数,Activator.CreateInstance
将抛出异常。任何像样的容器都可以处理这个功能,你可以为所有类型使用构造函数注入。
如果您不能或不想使用DI容器,请确保它已经过良好测试。