【发布时间】:2012-04-25 15:56:34
【问题描述】:
小问题
我应该把抽象工厂接口和实际工厂放在哪里?
概述
我正在编写一个简单的视频转码应用程序,我正在尝试解决依赖注入问题。
我在 Visual Studio 中将我的应用程序分成了几个项目。
- 应用引擎使用的转码器类库
- 应用程序引擎的一个类库,将由 gui 或控制台界面使用
- 一个控制台应用程序,现在将成为主要用户界面
没有 DI
这是依赖注入之前的一切
转码器库:
namespace SimpleFFmpeg {
public interface ITranscoder {
void Transcode(String fileName);
}
public class Transcoder:ITranscoder {
// ...
public void Transcode(String fileName) {
// do transcoding stuff
}
// ...
}
}
PusherEngine 库:
using SimpleFFmpeg;
namespace PusherLib {
public class PusherEngine {
private readonly List<VideoItem> _items;
public PusherEngine() {
_items = new List<VideoItem>();
}
// ...
public void processItems() {
foreach (VideoItem item in _items) {
ITranscoder t = new Transcoder();
t.Transcode(item.FileName);
}
}
// ...
}
}
实际应用:
namespace Pusher {
class Program {
static void Main(string[] args) {
PusherEngine pe = new PusherEngine();
pe.addVideoItem(new VideoItem(...));
pe.processItems();
}
}
}
重构以使用 DI
我创建了一个通用抽象工厂接口,就像这个问题中建议的那样:Creating new instances while still using Dependency Injection
public interface IFactory<T> {
T Get();
}
接下来我创建一个创建 ITranscoders 的工厂
public class TranscoderFactory: IFactory<ITranscoder> {
public ITranscoder Get() {
return new SimpleFFmpeg.Transcoder();
}
}
然后我修改 PusherEngine 以在构造函数中要求工厂依赖:
using SimpleFFmpeg;
namespace PusherLib {
public class PusherEngine {
private readonly IFactory<ITranscoder> _transcoderFactory;
private readonly List<VideoItem> _items;
public PusherEngine(IFactory<ITranscoder> transcoderFactory) {
_items = new List<VideoItem>();
_transcoderFactory = transcoderFactory;
}
// ...
public void processItems() {
foreach (VideoItem item in _items) {
ITranscoder t = _transcoderFactory.Get();
t.Transcode(item.FileName);
}
}
// ...
}
}
最后,在程序中是这样的:
namespace Pusher {
class Program {
static void Main(string[] args) {
IFactory<ITranscoder> f = new TranscoderFactory();
PusherEngine pe = new PusherEngine(f);
pe.addVideoItem(new VideoItem(...));
pe.processItems();
}
}
}
问题
应该在哪个库/项目中定义 IFactory 接口? TranscoderFactory 应该在哪个库/项目中定义?
它们是否存在于 Transcoder 库中?在 PusherLib 中?还是在实际的前端应用程序中? 我正在寻找最佳做法。
谢谢!
【问题讨论】:
-
+1 表示结构良好且书面问题...
-
也许我没抓住重点,或者这个例子被过度简化了,但是如果你不需要在运行时决定实例化什么,为什么还需要工厂呢?你可以只注入 ITranscoder。
-
@filpen 引擎需要为每个项目实例化一个新的 ITranscoder。如果有办法在没有工厂的情况下做到这一点,那么在这种特殊情况下这很可能是一个解决方案。
-
@luddet 好的,这几乎清除了它。我编辑了我的答案,希望能让你走上正轨。
标签: c# .net dependency-injection instantiation