简体   繁体   English

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

[英]Injecting a specific instance of an interface using Autofac

I have a controller and it receives a specific instance of an interface. 我有一个控制器,它接收一个特定的接口实例。

The interface looks something like this: 界面看起来像这样:

public interface IMyInterface
{
   ... implementation goes here
}

And then I have some classes that implement this interface like this: 然后我有一些实现这个接口的类,如下所示:

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

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

In my ControllerA I have the following constructor: 在我的ControllerA中,我有以下构造函数:

private ICustomerService customerService;
private IMyInterface myInterface;

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

In my global.ascx: 在我的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));
}

I specified that Autofac must supply the instance of ICustomerService. 我指定Autofac必须提供ICustomerService的实例。 How would I specify the instance type for IMyInterface? 我如何指定IMyInterface的实例类型? In this case for ControllerA I would like Autofac to inject a ClassA instance. 在这种情况下,对于ControllerA,我希望Autofac注入一个ClassA实例。 And for ControllerB I would like it to inject ClassB. 对于ControllerB,我希望它能够注入ClassB。 How would I do this? 我该怎么做?

UPDATED 2011-02-14: 更新2011-02-14:

Let me give you my real life situation. 让我告诉你我现实生活中的情况。 I have a NewsController whose constructor looks like this: 我有一个NewsController,其构造函数如下所示:

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

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

IMapper interface: IMapper界面:

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

I'm using AutoMapper. 我正在使用AutoMapper。 So my NewsMapper will look like this: 所以我的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);
   }
}

So how would you recommend me do this now? 那你现在怎么建议我这样做呢?

IIRC: IIRC:

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

Update 更新

Ok. 好。 Misread your question. 误读你的问题。

Actually, you should never ever do what you are asking. 实际上,你永远不应该做你想要的。 It's bound to give you problems. 它一定会给你带来麻烦。 Why? 为什么? Since there is no way to determine that the controllers can not work with the same interface. 由于无法确定控制器无法使用相同的接口。 Amongst others, you are breaking the Liskovs Substitution Principle. 除此之外,你正在打破Liskovs替代原则。 It might not be a problem for you now, but let your application grow and come back in a year and try to understand why it isn't working. 现在对你来说可能不是问题,但是让你的应用程序在一年内成长并回归并尝试理解它为什么不起作用。

Instead, create two new interfaces which derive from `IMyInterface´ and request those in the controllers. 相反,创建两个新的接口,这些接口派生自`IMyInterface'并请求控制器中的那些接口。

Update 2 更新2

Qouting snowbear: Qouting snowbear:

I disagree. 我不同意。 OP doesn't says that his controller cannot work with instance of another type, he says that he wants to inject instances of different types. OP没有说他的控制器无法使用其他类型的实例,他说他想要注入不同类型的实例。 Let's imagine he has some service to extract data and he has a service which wraps this data service and provides caching functionality. 让我们假设他有一些提取数据的服务,他有一个包装这个数据服务并提供缓存功能的服务。 I believe they should have the same interface in such situation and it is matter of DI to inject correct service 我认为在这种情况下它们应该具有相同的接口,并且注入正确的服务是DI的问题

OP says just that: Controller A cannot work same class as controller B. Why would he else want to get different classes in different controllers for the same interface? OP只是说:控制器A不能像控制器B一样工作。为什么他还想在同一个接口的不同控制器中获得不同的类?

Brendan: 布兰登:

I personally would create a INewsMapper interface to make everything clear and sound. 我个人会创建一个INewsMapper接口,使一切都清晰和完整。 But if you do not want to do that: Go for a generic interface with the aggregate root as type parameter. 但是,如果您不想这样做:使用聚合根作为类型参数寻找通用接口。

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)
{
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM