diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
index 76ba2ae..5d08331 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -385,6 +385,31 @@ protected function addDependency($type, $name) {
   }
 
   /**
+   * Adds multiple dependencies.
+   *
+   * @param array $dependencies.
+   *   An array of dependencies keyed by the type of dependency. One example:
+   * @code
+   * array(
+   *   'module' => array(
+   *     'node',
+   *     'field',
+   *     'image'
+   *   ),
+   * );
+   * @endcode
+   *
+   * @see ::addDependency
+   */
+  protected function addDependencies(array $dependencies) {
+    foreach ($dependencies as $dependency_type => $list) {
+      foreach ($list as $name) {
+        $this->addDependency($dependency_type, $name);
+      }
+    }
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getConfigDependencyName() {
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
index 030bd50..f242dc0 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
@@ -51,7 +51,12 @@ class Field extends FieldPluginBase {
    *
    * @var \Drupal\Core\Field\FieldDefinitionInterface
    */
-  public $field_info;
+  public $fieldDefinition;
+
+  /**
+   * The field config.
+   */
+  protected $fieldConfig;
 
   /**
    * Does the field supports multiple field values.
@@ -141,18 +146,43 @@ public static function create(ContainerInterface $container, array $configuratio
   }
 
   /**
+   * Gets the field definition.
+   *
+   * @return \Drupal\Core\Field\FieldDefinitionInterface
+   *   The field definition used by this handler.
+   */
+  protected function getFieldDefinition() {
+    if (!$this->fieldDefinition) {
+      $field_config = $this->getFieldConfig();
+      $this->fieldDefinition = FieldDefinition::createFromFieldStorageDefinition($field_config);
+    }
+    return $this->fieldDefinition;
+  }
+
+  /**
+   * Gets the field configuration.
+   *
+   * @return \Drupal\field\FieldConfigInterface
+   */
+  protected function getFieldConfig() {
+    if (!$this->fieldConfig) {
+      $this->fieldConfig = FieldHelper::fieldInfo()->getField($this->definition['entity_type'], $this->definition['field_name']);
+    }
+    return $this->fieldConfig;
+  }
+
+  /**
    * Overrides \Drupal\views\Plugin\views\field\FieldPluginBase::init().
    */
   public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
     parent::init($view, $display, $options);
 
-    $field_storage_definition = FieldHelper::fieldInfo()->getField($this->definition['entity_type'], $this->definition['field_name']);
-    $this->field_info = FieldDefinition::createFromFieldStorageDefinition($field_storage_definition);
     $this->multiple = FALSE;
     $this->limit_values = FALSE;
 
-    $cardinality = $this->field_info->getCardinality();
-    if ($this->field_info->isMultiple()) {
+    $field_info = $this->getFieldDefinition();
+    $cardinality = $field_info->getCardinality();
+    if ($field_info->isMultiple()) {
       $this->multiple = TRUE;
 
       // If "Display all values in the same row" is FALSE, then we always limit
@@ -180,7 +210,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
   public function access(AccountInterface $account) {
     $base_table = $this->get_base_table();
     $access_controller = $this->entityManager->getAccessController($this->definition['entity_tables'][$base_table]);
-    return $access_controller->fieldAccess('view', $this->field_info, $account);
+    return $access_controller->fieldAccess('view', $this->getFieldDefinition(), $account);
   }
 
   /**
@@ -227,6 +257,7 @@ public function query($use_groupby = FALSE) {
       unset($fields[$entity_type_key]);
     }
 
+    $field_definition = $this->getFieldDefinition();
     if ($use_groupby) {
       // Add the fields that we're actually grouping on.
       $options = array();
@@ -240,8 +271,8 @@ public function query($use_groupby = FALSE) {
       // Go through the list and determine the actual column name from field api.
       foreach ($options as $column) {
         $name = $column;
-        if (isset($this->field_info['storage_details']['sql'][$rkey][$this->table][$column])) {
-          $name = $this->field_info['storage_details']['sql'][$rkey][$this->table][$column];
+        if (isset($field_definition['storage_details']['sql'][$rkey][$this->table][$column])) {
+          $name = $field_definition['storage_details']['sql'][$rkey][$this->table][$column];
         }
 
         $fields[$column] = $name;
@@ -256,7 +287,7 @@ public function query($use_groupby = FALSE) {
       $this->addAdditionalFields($fields);
 
       // Filter by langcode, if field translation is enabled.
-      $field = $this->field_info;
+      $field = $field_definition;
       if ($field->isTranslatable() && !empty($this->view->display_handler->options['field_langcode_add_to_query'])) {
         $column = $this->tableAlias . '.langcode';
         // By the same reason as field_language the field might be Language::LANGCODE_NOT_SPECIFIED in reality so allow it as well.
@@ -401,7 +432,7 @@ protected function defineOptions() {
   public function buildOptionsForm(&$form, &$form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    $field = $this->field_info;
+    $field = $this->getFieldDefinition();
     $formatters = $this->formatterPluginManager->getOptions($field->getType());
     $column_names = array_keys($field->getColumns());
 
@@ -480,7 +511,7 @@ public function buildOptionsForm(&$form, &$form_state) {
    * Provide options for multiple value fields.
    */
   function multiple_options_form(&$form, &$form_state) {
-    $field = $this->field_info;
+    $field = $this->getFieldDefinition();
 
     $form['multiple_field_settings'] = array(
       '#type' => 'details',
@@ -607,7 +638,7 @@ public function buildGroupByForm(&$form, &$form_state) {
     // With "field API" fields, the column target of the grouping function
     // and any additional grouping columns must be specified.
 
-    $field_columns = array_keys($this->field_info->getColumns());
+    $field_columns = array_keys($this->getFieldDefinition()->getColumns());
     $group_columns = array(
       'entity_id' => t('Entity ID'),
     ) + array_map('ucfirst', array_combine($field_columns, $field_columns));
@@ -832,14 +863,14 @@ function render_item($count, $item) {
   }
 
   protected function documentSelfTokens(&$tokens) {
-    $field = $this->field_info;
+    $field = $this->getFieldDefinition();
     foreach ($field->getColumns() as $id => $column) {
       $tokens['[' . $this->options['id'] . '-' . $id . ']'] = t('Raw @column', array('@column' => $id));
     }
   }
 
   protected function addSelfTokens(&$tokens, $item) {
-    $field = $this->field_info;
+    $field = $this->getFieldDefinition();
     foreach ($field->getColumns() as $id => $column) {
       // Use \Drupal\Component\Utility\Xss::filterAdmin() because it's user data
       // and we can't be sure it is safe. We know nothing about the data,
@@ -866,7 +897,7 @@ protected function addSelfTokens(&$tokens, $item) {
    * according to the settings.
    */
   function field_langcode(EntityInterface $entity) {
-    if ($this->field_info->isTranslatable()) {
+    if ($this->getFieldDefinition()->isTranslatable()) {
       $default_langcode = language_default()->id;
       $langcode = str_replace(
         array('***CURRENT_LANGUAGE***', '***DEFAULT_LANGUAGE***'),
@@ -888,4 +919,13 @@ function field_langcode(EntityInterface $entity) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getDependencies() {
+    // Add the module providing the configured field as a dependency.
+    return array('entity' => array($this->getFieldConfig()->getConfigDependencyName()));
+  }
+
+
 }
diff --git a/core/modules/views/lib/Drupal/views/Entity/View.php b/core/modules/views/lib/Drupal/views/Entity/View.php
index 304d1f8..c3e19aa 100644
--- a/core/modules/views/lib/Drupal/views/Entity/View.php
+++ b/core/modules/views/lib/Drupal/views/Entity/View.php
@@ -12,7 +12,6 @@
 use Drupal\views\Views;
 use Drupal\views_ui\ViewUI;
 use Drupal\views\ViewStorageInterface;
-use Drupal\views\ViewExecutable;
 
 /**
  * Defines a View configuration entity class.
@@ -273,28 +272,43 @@ public function calculateDependencies() {
 
     // Ensure that the view is dependant on the module that implements the view.
     $this->addDependency('module', $this->module);
-    // Ensure that the view is dependant on the module that provides the schema
+    // Ensure that the view is dependent on the module that provides the schema
     // for the base table.
-    $schema = drupal_get_schema($this->base_table);
+    $schema = $this->drupalGetSchema($this->base_table);
     if ($this->module != $schema['module']) {
       $this->addDependency('module', $schema['module']);
     }
 
     $handler_types = array();
-    foreach (ViewExecutable::getHandlerTypes() as $type) {
+    foreach (Views::getHandlerTypes() as $type) {
       $handler_types[] = $type['plural'];
     }
+
     foreach ($this->get('display') as $display) {
+      // Collect all dependencies of all handlers.
       foreach ($handler_types as $handler_type) {
         if (!empty($display['display_options'][$handler_type])) {
           foreach ($display['display_options'][$handler_type] as $handler) {
+            // Add the provider as dependency.
             if (isset($handler['provider']) && empty($handler['optional'])) {
               $this->addDependency('module', $handler['provider']);
             }
+            // Add the additional dependencies from the handler configuration.
+            if (!empty($handler['dependencies'])) {
+              $this->addDependencies($handler['dependencies']);
+            }
           }
         }
       }
+
+      // Collect all dependencies of plugins.
+      foreach (Views::getPluginTypes('plugin') as $plugin_type) {
+        if (!empty($display['display_options'][$plugin_type]['options']['dependencies'])) {
+          $this->addDependencies($display['display_options'][$plugin_type]['options']['dependencies']);
+        }
+      }
     }
+
     return $this->dependencies;
   }
 
@@ -386,4 +400,11 @@ public function mergeDefaultDisplaysOptions() {
     $this->set('display', $displays);
   }
 
+  /**
+   * Wraps drupal_get_schema().
+   */
+  protected function drupalGetSchema($table = NULL, $rebuild = FALSE) {
+    return drupal_get_schema($table, $rebuild);
+  }
+
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
index e0bf952..cbff847 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
@@ -168,6 +168,7 @@ protected function defineOptions() {
     $options['relationship'] = array('default' => 'none');
     $options['group_type'] = array('default' => 'group');
     $options['admin_label'] = array('default' => '', 'translatable' => TRUE);
+    $options['dependencies'] = array('default' => array());
 
     return $options;
   }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php
index ba15dbb..f25e2d0 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php
@@ -424,4 +424,16 @@ public static function preRenderFlattenData($form) {
     return $form;
   }
 
+  /**
+   * Returns an array of module dependencies for this plugin.
+   *
+   * Dependencies are a list of module names, which might depend on the
+   * configuration.
+   *
+   * @return array
+   */
+  public function getDependencies() {
+    return array();
+  }
+
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
index 50e8c85..4ed08e4 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
@@ -767,6 +767,7 @@ protected function defaultDisplayOptions() {
     foreach ($display_options as &$options) {
       $options['options'] = array();
       $options['provider'] = 'views';
+      $options['dependencies'] = array();
     }
 
     // Add a least one field so the view validates and the user has a preview.
diff --git a/core/modules/views/lib/Drupal/views/ViewStorageInterface.php b/core/modules/views/lib/Drupal/views/ViewStorageInterface.php
index 089f428..31b9f7b 100644
--- a/core/modules/views/lib/Drupal/views/ViewStorageInterface.php
+++ b/core/modules/views/lib/Drupal/views/ViewStorageInterface.php
@@ -29,4 +29,5 @@ public function &getDisplay($display_id);
    * Add defaults to the display options.
    */
   public function mergeDefaultDisplaysOptions();
+
 }
diff --git a/core/modules/views/tests/Drupal/views/Tests/Entity/ViewTest.php b/core/modules/views/tests/Drupal/views/Tests/Entity/ViewTest.php
new file mode 100644
index 0000000..0aae557
--- /dev/null
+++ b/core/modules/views/tests/Drupal/views/Tests/Entity/ViewTest.php
@@ -0,0 +1,97 @@
+<?php
+use Drupal\views\Entity\View;
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\Entity\ViewTest.
+ */
+
+namespace Drupal\views\Tests\Entity {
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Entity\EntityType;
+use Drupal\Tests\UnitTestCase;
+use Drupal\views\Entity\View;
+
+/**
+ * Tests the view entity.
+ *
+ * @coversDefaultClass \Drupal\views\Entity\View
+ */
+class ViewTest extends UnitTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'View entity test',
+      'description' => 'Tests the \Drupal\views\Entity\View class.',
+      'group' => 'Views',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+
+    // Setup the entity manager.
+    $entity_definition = new EntityType(array('id' => 'view'));
+    $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
+    $entity_manager->expects($this->any())
+      ->method('getDefinition')
+      ->will($this->returnValue($entity_definition));
+    $container_builder = new ContainerBuilder();
+    $container_builder->set('entity.manager', $entity_manager);
+
+    // Setup the string translation.
+    $string_translation = $this->getStringTranslationStub();
+    $container_builder->set('string_translation', $string_translation);
+    \Drupal::setContainer($container_builder);
+  }
+
+  /**
+   * Tests calculating dependencies.
+   *
+   * @covers ::calculateDependencies
+   * @dataProvider calculateDependenciesProvider
+   */
+  public function testCalculateDependencies($values, $deps) {
+    $view = new TestView($values, 'view');
+    $this->assertEquals(array('module' => $deps), $view->calculateDependencies());
+  }
+
+  public function calculateDependenciesProvider(){
+    $handler['display']['default']['display_options']['fields']['example']['dependencies'] = array();
+    $handler['display']['default']['display_options']['fields']['example2']['dependencies']['module'] = array('views', 'field');
+    $handler['display']['default']['display_options']['fields']['example3']['dependencies']['module'] = array('views', 'image');
+
+    $plugin['display']['default']['display_options']['access']['options']['dependencies'] = array();
+    $plugin['display']['default']['display_options']['row']['options']['dependencies']['module'] = array('views', 'field');
+    $plugin['display']['default']['display_options']['style']['options']['dependencies']['module'] = array('views', 'image');
+
+    return array(
+      array(array(), array('node', 'views')),
+      array($handler, array('field', 'image', 'node', 'views')),
+      array($plugin, array('field', 'image', 'node', 'views')),
+    );
+  }
+}
+
+class TestView extends View {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function drupalGetSchema($table = NULL, $rebuild = FALSE) {
+    $result = array();
+    if ($table == 'node') {
+      $result['module'] = 'node';
+    }
+    return $result;
+  }
+
+}
+
+}
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigHandler.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigHandler.php
index 4f3bc7b..8533e69 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigHandler.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigHandler.php
@@ -238,6 +238,14 @@ public function submitForm(array &$form, array &$form_state) {
     // extra stuff on the form is not sent through.
     $handler->unpackOptions($handler->options, $options, NULL, FALSE);
 
+    // Add any dependencies as the handler is saved. Put it here so
+    // it does not need to be declared in defineOptions().
+    if ($dependencies = $handler->getDependencies()) {
+      $handler->options['dependencies'] = $dependencies;
+    }
+    // Add the module providing the handler as a dependency as well.
+    $handler->options['dependencies']['module'][] = $handler->definition['provider'];
+
     // Store the item back on the view
     $executable->setHandler($form_state['display_id'], $form_state['type'], $form_state['id'], $handler->options);
 
