2010-12-06 48 views
3

我刚刚开始使用IoC框架,并且一直在玩Autofac。使用Autofac的IoC

在下面的示例代码中,我注册了两个完全不同的类(在global.asax中),它们都实现了相同的接口,我想知道我们如何确保Autofac使用正确的接口?目前,我的控制器之一以IPhotoBlogRepository作为其构造函数,通过PhotoBlogRepositoryTestRepository,这取决于哪一个出现在下面的代码中的第一个/最后一个。

builder.RegisterType<PhotoBlogRepository>().As<IPhotoBlogRepository>(); 
builder.RegisterType<TestRepository>().As<IPhotoBlogRepository>(); 

回答

7

这是设计。一个容器不能知道你想要的服务。如果在生产代码中只有一个接口的实现,那么你的注册代码应该确保不会有一个以上的服务被注册。

如果您打算支持多种实现,那么您的控制器可能会依赖于IEnumerable<IPhotoBlogRepository>。 Autofac将为控制器提供实现该接口的所有注册服务的集合。

如果控制器需要更细粒度的控制,请看Autofac supports metadata

这就是说:从您的示例中,我看到您正在注册接口的测试实现。在单元测试中,我很少从容器中解析SUT(在这种情况下是你的控制器),而是直接实例化它。这消除了使用假的“替换”真实服务的问题,因为您将始终将它们直接交给控制器构造函数。

+0

对不起,我的代码在这里误导了'Test'这个词。没有单元测试,我只是简单地创建了几个虚拟类来试图了解它是如何工作的,并碰巧创建了我的一个类TestRepository。 – marcusstarnes 2010-12-06 17:51:01

2

正如上面所指出的,元数据可能是你想要去与此的方式,但如果你只是想简单地确保第一实现选择,那么你应该使用PreserveExistingDefaults()所有额外注册,即:

builder.RegisterType<PhotoBlogRepository>().As<IPhotoBlogRepository>(); 
builder.RegisterType<TestRepository>().As<IPhotoBlogRepository>().PreserveExistingDefaults(); 

最后一次注册是将被选作默认值的那个,而不应用PreserveExistingDefaults()