Question: How can we assign a theme in Magento 2.1 to a store using setup scripts?

Thank you

Answer: 
Create a new *InstallData* (or *UpgradeData*) script in either a new module or a fitting pre-existing module.

Here is a simple example for a complete `InstallData` script. Simply replace the `THEME_NAME` constant found at the top of the class with your own theme name. For example, if you wanted to assign the default Magento 2 luma theme, you would write:

```
const THEME_NAME = 'Magento/luma';

```

*(Make sure the **V**endor starts with an uppercase and the **t**heme with a lower case letter!)*

You can find your theme name by simply looking at the `registration.php` in the directory of your theme (found in *app/design/frontend/*), it's probably easiest to copy paste it from here to prevent any typos:

```
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::THEME,
    'frontend/Vendor/theme',
    __DIR__
);

```

The full `InstallData.php` script looks like this, alternatively you can add it to an `UpgradeData.php` as well, you mainly need the assignTheme() method from the bottom and inject all the required classes into the constructor:

```
<?php
namespace Medline\Theme\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\Store;

/**
 * @codeCoverageIgnore
 * @SuppressWarnings(PHPMD)
 */
class InstallData implements InstallDataInterface
{
    const THEME_NAME = 'Vendor/theme';

    /**
     * @var \Magento\Theme\Model\Config
     */
    private $config;

    /**
     * @var \Magento\Theme\Model\ResourceModel\Theme\CollectionFactory
     */
    private $collectionFactory;

    /**
     * InstallData constructor.
     * @param \Magento\Theme\Model\ResourceModel\Theme\CollectionFactory $collectionFactory
     * @param \Magento\Theme\Model\Config $config
     */
    public function __construct(
        \Magento\Theme\Model\ResourceModel\Theme\CollectionFactory $collectionFactory,
        \Magento\Theme\Model\Config $config
    ) {
        $this->collectionFactory = $collectionFactory;
        $this->config = $config;
    }

    /**
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        $this->assignTheme();

        $setup->endSetup();
    }

    /**
     * Assign Theme
     *
     * @return void
     */
    protected function assignTheme()
    {
        $themes = $this->collectionFactory->create()->loadRegisteredThemes();
        /**
         * @var \Magento\Theme\Model\Theme $theme
         */
        foreach ($themes as $theme) {
            if ($theme->getCode() == self::THEME_NAME) {
                $this->config->assignToStore(
                    $theme,
                    [Store::DEFAULT_STORE_ID],
                    ScopeConfigInterface::SCOPE_TYPE_DEFAULT
                );
            }
        }
    }
}

```
Better to use `\Magento\Framework\View\Design\Theme\ListInterface` instead of `\Magento\Theme\Model\ResourceModel\Theme\CollectionFactory`. **ListInterface** have method **getThemeByFullPath**, so your code would be:

```
<?php
namespace Vendor\Module\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\Store;

/**
 * Class InstallData
 */
class InstallData implements InstallDataInterface
{
    const THEME_FULL_PATH = 'frontend/Vendor/theme';

    /**
     * @var \Magento\Theme\Model\Config
     */
    private $config;

    /**
     * @var \Magento\Framework\View\Design\Theme\ListInterface $themeList
     */
    private $themeList;

    /**
     * InstallData constructor.
     *
     * @param \Magento\Framework\View\Design\Theme\ListInterface $themeList
     * @param \Magento\Theme\Model\Config $config
     */
    public function __construct(
        \Magento\Framework\View\Design\Theme\ListInterface $themeList,
        \Magento\Theme\Model\Config $config
    ) {
        $this->themeList = $themeList;
        $this->config = $config;
    }

    /**
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        $this->assignTheme();

        $setup->endSetup();
    }

    /**
     * Assign Theme
     *
     * @return void
     */
    protected function assignTheme()
    {
        /** @var \Magento\Framework\View\Design\ThemeInterface $theme */
        $theme = $this->themeList->getThemeByFullPath(self::THEME_FULL_PATH);

        if ($theme->getId()) {
            $this->config->assignToStore($theme, [Store::DEFAULT_STORE_ID], ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
        }
    }
}

```

And you should add di.xml to your module

```
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Vendor\Module\Setup\InstallData">
        <arguments>
            <argument name="themeList" xsi:type="object">Magento\Theme\Model\ResourceModel\Theme\Collection</argument>
        </arguments>
    </type>
</config> 

```