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

时间:2010-12-21 10:06:55

标签: asp.net-mvc dependency-injection asp.net-mvc-3 automapper autofac

我使用ASP.NET MVC 3和Autofac进行依赖注入。我正在使用AutoMapper进行映射。

我有一个IMapper类,我用于所有模型视图映射。所以我的任何映射类都可以实现这个接口。在下面的控制器中,构造函数接收一个IMapper实例,并且在我的用户控制器中它可能会收到一个不同的实例,可能是userMapper。回到下面的代码,我有一个名为NewsMapper的类,它实现了IMapper。如何设置依赖注入,以便此控制器必须接收NewsMapper的实例?请记住,我可能有另一个名为UserMapper的映射器。

我有以下控制器:

public class NewsController
{
   private INewsService newsService;
   private IMapper newsMapper;

   public NewsController(INewsService newsService, IMapper newsMapper)
   {
      if (newsService == null)
      {
         throw new ArgumentNullException("newsService");
      }

      if (newsMapper == null)
      {
         throw new ArgumentNullException("newsMapper");
      }

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

我在global.asax.cs中有以下配置:

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<NewsService>().As<INewsService>();
builder.RegisterType<NewsRepository>().As<INewsRepository>();

更新:

我的IMapper界面:

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

我的NewsMapper类:

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

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

我执行映射的控制器操作方法:

[HttpPost]
public ActionResult Create(NewsViewModel newsViewModel)
{
   // Check model state
   if (!ModelState.IsValid)
   {
      return View("Create", newsViewModel);
   }

   // Do mapping
   var news = (News)newsMapper.Map(newsViewModel, typeof(NewsViewModel), typeof(News));

   // Add to database via news service

   // Redirect to list view
   return RedirectToAction("List", "News");
}

1 个答案:

答案 0 :(得分:5)

这里的问题是IMapper合同的广泛性。它过于笼统 - NewsController想要将News映射到NewsViewModel,但IMapper只是说“将某些东西映射到某个东西。”

相反,请查看创建IMapper<TFrom,TTo>等通用变体。然后,您可以设置容器,以便NewsController收到明确无误的IMapper<News,NewsModel>,并且应该唯一匹配NewsMapper组件(但是您决定将其设置为。)

修改

有关通用映射器主题的示例/变体,请参阅: