使用Autofac注入接口的特定实例

时间:2011-02-14 07:14:52

标签: c# dependency-injection inversion-of-control automapper autofac

我有一个控制器,它接收一个特定的接口实例。

界面如下所示:

public interface IMyInterface
{
   ... implementation goes here
}

然后我有一些实现此接口的类,如下所示:

public class MyClassA : IMyInterface
{
   ... implementation goes here
}

public class MyClassB : IMyInterface
{
   ... implementation goes here
}

在我的ControllerA中,我有以下构造函数:

private ICustomerService customerService;
private IMyInterface myInterface;

puvlic ControllerA(ICustomerService customerService, IMyInterface myInterface)
{
   this.customerService = customerService;
   this.myInterface = myInterface;
}

在我的global.ascx中:

protected void Application_Start()
{
   // Autofac
   var builder = new ContainerBuilder();
   builder.RegisterControllers(Assembly.GetExecutingAssembly());
   builder.RegisterType<NewsService>().As<INewsService>();

   IContainer container = builder.Build();
   DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}

我指定Autofac必须提供ICustomerService的实例。我如何指定IMyInterface的实例类型?在这种情况下,对于ControllerA,我希望Autofac注入一个ClassA实例。对于ControllerB,我希望它能够注入ClassB。我该怎么做?

更新2011-02-14:

让我告诉你我的真实生活情况。我有一个NewsController,其构造函数如下所示:

public NewsController(INewsService newsService, IMapper newsMapper)
{
   Check.Argument.IsNotNull(newsService, "newsService");
   Check.Argument.IsNotNull(newsMapper, "newsMapper");

   this.newsService = newsService;
   this.newsMapper = newsMapper;
}

IMapper界面:

public interface IMapper
{
   object Map(object source, Type sourceType, Type destinationType);
}

我正在使用AutoMapper。所以我的NewsMapper看起来像这样:

public class NewsMapper : IMapper
{
   static NewsMapper()
   {
      Mapper.CreateMap<News, NewsEditViewData>();
      Mapper.CreateMap<NewsEditViewData, News>();
   }

   public object Map(object source, Type sourceType, Type destinationType)
   {
      return Mapper.Map(source, sourceType, destinationType);
   }
}

那你现在怎么建议我这样做?

1 个答案:

答案 0 :(得分:5)

IIRC:

builder.RegisterType<MyClassB>().As<IMyInterface>()

更新

确定。误读了你的问题。

实际上,你永远不应该做你想要的。它一定会给你带来麻烦。为什么?由于无法确定控制器无法使用相同的接口。除此之外,你正在打破Liskovs替代原则。现在对你来说可能不是问题,但是让你的应用程序在一年内成长并回归并尝试理解它为什么不起作用。

相反,创建两个新的接口,这些接口派生自`IMyInterface'并请求控制器中的接口。

更新2

Qouting snowbear:

  

我不同意。 OP并没有说他的   控制器无法与实例一起工作   另一种类型,他说他想要   注入不同的实例   类型。让我们想象他有一些   服务提取数据,他有一个   包装此数据服务的服务   并提供缓存功能。一世   相信他们应该有同样的   这种情况下的接口就是这样   DI注入正确服务的问题

OP说的是:控制器A不能像控制器B一样工作。为什么他还想在同一个接口的不同控制器中获得不同的类?

<强>布伦丹:

我个人会创建一个INewsMapper界面,让一切都清晰明了。但是,如果您不想这样做:使用聚合根作为类型参数寻找通用接口。

public interface IMapper<T> : IMapper where T : class
{

}

public class NewsMapper : IMapper<News>
{
   static NewsMapper()
   {
      Mapper.CreateMap<News, NewsEditViewData>();
      Mapper.CreateMap<NewsEditViewData, News>();
   }

   public object Map(object source, Type sourceType, Type destinationType)
   {
      return Mapper.Map(source, sourceType, destinationType);
   }
}

public NewsController(INewsService newsService, IMapper<News> newsMapper)
{
}