[英]Injecting a specific instance of an interface using 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);
}
}
那你现在怎么建议我这样做呢?
IIRC:
builder.RegisterType<MyClassB>().As<IMyInterface>()
好。 误读你的问题。
实际上,你永远不应该做你想要的。 它一定会给你带来麻烦。 为什么? 由于无法确定控制器无法使用相同的接口。 除此之外,你正在打破Liskovs替代原则。 现在对你来说可能不是问题,但是让你的应用程序在一年内成长并回归并尝试理解它为什么不起作用。
相反,创建两个新的接口,这些接口派生自`IMyInterface'并请求控制器中的那些接口。
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)
{
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.