MVC 3 И MEF и добавление плагинов к основному приложению - PullRequest
4 голосов
/ 09 сентября 2011

Я новичок в MEF, и я действительно запутался!Есть много полезных статей, а также вопросы и ответы здесь в stackoverflow.Я скачал пример, который @ matthew-abbott загрузил в его блоге , но я не знаю, как добавить новые плагины или расширение для расширения основного веб-приложения, я имею в виду то, что вы видите здесь .

Отредактировано: также я использую Entity Framework, Code First Approach и Unit of work для своего приложения уровня доступа к данным, что если моим плагинам нужен доступ к данным и (я имею в виду плагину себя есть модели) хочет использовать DAL, который я создал?Как вы знаете, каждый раз, когда модель изменяется, DbContext выдает и выдает ошибку и сообщает о повторном создании БД. Есть ли какой-либо способ или другой ORM, который принимает расширение DAL динамически?

1 Ответ

5 голосов
/ 09 сентября 2011

Этот конкретный пример показывает, как мы можем интегрировать MEF с новым DependencyResolver MVC3, который обеспечивает механизм определения местоположения службы для различных точек расширения в архитектуре MVC.В моем блоге есть еще несколько статей, в которых подробно описывается, как может работать возможная архитектура плагинов. Они доступны по адресу:

  1. Модульный ASP.NET MVC с использованием инфраструктуры управляемых расширений (MEF), часть первая
  2. модульный ASP.NET MVC с использованием инфраструктуры управляемой расширяемости (MEF), часть вторая
  3. модульный ASP.NET MVCиспользование инфраструктуры управляемой расширяемости (MEF), часть третья

Есть также множество фантастических статей, мои рекомендации также будут читать:

ASP.NET MVC и платформа Managed Extensibility Framework (MEF) от Maarten Balliauw Определение веб-областей с помощью MEF Тимом Робертсом

MVC - это очень гибкая архитектура, существует множество способов ее расширения, но из-за особенностей работы приложений ASP.NET в IIS необходимо очень тщательно рассмотреть время жизни детали.Например, контроллеры могут использоваться только для одного запроса, поэтому вам может потребоваться, чтобы ваши контроллеры имели определенный CreationPolicy.Статья Тима Роберта, посвященная веб-деталям, особенно хороша для чтения.

Надеюсь, что этого достаточно, чтобы указать правильное направление.

Редактировать: из-за модульной природы, которую обеспечивает MEF,важно убедиться, что ваши разные слои отделены.Вы указали, что используете Entity Framework, но в действительности EF следует использовать только на уровне данных.Как правило, архитектура MVC будет продвигать модели представлений поверх моделей доменов.Для этого, вероятно, полезно использовать что-то похожее на шаблон репозитория, например, вот макет UserRepository:

[Export(typeof(IUserRepository))]
public class UserRepository : IUserRepository
{
  public IEnumerable<UserViewModel> GetUsers() 
  {
    // Get values here from EF as domain models
    // And return them as view models?
  }
}

, который мы можем экспортировать и вставить в контроллер:

[ExportController("User"), PartCreationPolicy(CreationPolicy.NonShared)]
public class UserController : Controller
{
  private readonly IUserRepository _repo;

  [ImportingConstructor]
  public UserController(IUserRepository repo)
  {
    if (repo == null)
      throw new ArgumentNullException("repo");

    _repo = repo;
  }

  public ActionResult Index()
  {
    var users = _repo.GetUsers();
    return View(users);
  }
}

Это просто очень простой пример, но, как и многие контейнеры IoC, MEF также поддерживает внедрение зависимостей.До тех пор, пока деталь обеспечивает подходящий экспорт, ее можно импортировать (либо с помощью внедрения свойства, либо с помощью конструктора) в другую деталь во время компоновки.

Я бы не рекомендовал использовать EF для ваших представлений, так какделает их явно зависимыми от него.Заботясь об отделении и представлении только нужных типов на нужных уровнях, ваша архитектура станет намного более надежной, гибкой и тестируемой, что сделает ее обслуживание и обновление намного проще.В качестве еще одного быстрого примера, вот как мы могли бы протестировать наш контроллер:

[Test]
public void UserController_CreatesViewResult_WithListOfUsers()
{
  var mock = new Mock<IUserRepository>();
  mock.Setup(m => m.GetUsers()).Returns(new[] { new UserViewModel { Name = "Matt" } });

  var controller = new UserController(mock.Object);

  var result = controller.Index();

  Assert.That(result is ViewResult);
  // Other assertions.
}

Поскольку я не тесно связал EF со своим видом, мой контроллер намного более тестируем, я могу смоделировать подходящий репозиторий ипроверить, где мне нужно.

Важным является планирование вашей архитектуры.

...