Внедрение определенного экземпляра интерфейса с использованием Autofac - PullRequest
0 голосов
/ 21 декабря 2010

Я использую 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 Ответ

5 голосов
/ 22 декабря 2010

Проблема здесь заключается в широте IMapper контракта. Оно слишком общее - NewsController хочет сопоставить что-то вроде News с NewsViewModel, но IMapper просто говорит "сопоставляет что-то с чем-то".

Вместо этого взгляните на создание общего варианта, такого как IMapper<TFrom,TTo>. Затем вы можете настроить контейнер так, чтобы NewsController получал IMapper<News,NewsModel>, который является однозначным и должен однозначно соответствовать компоненту NewsMapper (однако вы решаете установить его).

Редактировать

Примеры / варианты общей темы сопоставления см .:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...