diff --git a/GUI/DataLoaders/AutomaticDataLoader1D.h b/GUI/DataLoaders/AutomaticDataLoader1D.h
index 992b55ee7afd9ff2f838272551c9374fc39f1484..6a5bc7c50481540d470c51e4395d13e95438faca 100644
--- a/GUI/DataLoaders/AutomaticDataLoader1D.h
+++ b/GUI/DataLoaders/AutomaticDataLoader1D.h
@@ -16,7 +16,7 @@
 #define BORNAGAIN_GUI_DATALOADERS_AUTOMATICDATALOADER1D_H
 
 #include "Device/Data/OutputData.h"
-#include "GUI/DataLoaders/AbstractDataLoader1D.h"
+#include "GUI/Models/AbstractDataLoader1D.h"
 
 //! The legacy importer for reflectometry, with no user interaction.
 
diff --git a/GUI/DataLoaders/AutomaticDataLoader1DResultModel.h b/GUI/DataLoaders/AutomaticDataLoader1DResultModel.h
index edf3965aaa3a271a9d572bdd9fa100b5d55ef984..fe435e3664b69c713ed92a632db52e8bafc0928b 100644
--- a/GUI/DataLoaders/AutomaticDataLoader1DResultModel.h
+++ b/GUI/DataLoaders/AutomaticDataLoader1DResultModel.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_DATALOADERS_AUTOMATICDATALOADER1DRESULTMODEL_H
 #define BORNAGAIN_GUI_DATALOADERS_AUTOMATICDATALOADER1DRESULTMODEL_H
 
-#include "GUI/DataLoaders/AbstractDataLoaderResultModel.h"
+#include "GUI/Models/AbstractDataLoaderResultModel.h"
 
 class RealDataItem;
 
diff --git a/GUI/DataLoaders/DataLoaderUtil.cpp b/GUI/DataLoaders/DataLoaderUtil.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b95d5e4381e09bd4c1e07f94bbe49d89d6fa9419
--- /dev/null
+++ b/GUI/DataLoaders/DataLoaderUtil.cpp
@@ -0,0 +1,56 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      GUI/DataLoaders/UserDefinedDataLoader1D.cpp
+//! @brief     Implements class UserDefinedDataLoader1D
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2021
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+//  ************************************************************************************************
+
+#include "GUI/DataLoaders/DataLoaderUtil.h"
+#include "GUI/DataLoaders/AutomaticDataLoader1D.h"
+#include "GUI/DataLoaders/QREDataLoader.h"
+#include "GUI/DataLoaders/UserDefinedDataLoader1D.h"
+#include "GUI/Models/DataLoaders1D.h"
+
+void cloneAsUserDefinedLoader(AbstractDataLoader1D* loader, const QString& name)
+{
+    loader->applyImportSettings();
+    auto clonedLoader = dynamic_cast<AbstractDataLoader1D*>(loader->clone());
+    const auto defaultProperties = loader->serialize();
+
+    DataLoaders1D::instance().addUserDefinedLoader
+        (new UserDefinedDataLoader1D(clonedLoader, name, defaultProperties));
+}
+
+
+namespace {
+
+//! simple factory method for a QREDataLoader
+QREDataLoader* createQREDataLoader() {
+    return new QREDataLoader();
+}
+
+//! simple factory method for a AutomaticDataLoader1D
+AutomaticDataLoader1D* createAutomaticDataLoader1D() {
+    return new AutomaticDataLoader1D();
+}
+
+}
+    
+//! register the concrete data loaders with the registration facility
+void register1DDataLoaders() {
+    // the ordering in here defines the ordering in the selection combo box in the open file dialog
+    // and also in the selection combo box on the format configuration page. Furthermore the first
+    // returned loader will be used as default in the open file dialog if it is started for the
+    // first time
+    DataLoaders1D::instance().addBuiltInLoader
+        (QREDataLoader().persistentClassName(), createQREDataLoader);
+    DataLoaders1D::instance().addBuiltInLoader
+        (AutomaticDataLoader1D().persistentClassName(), createAutomaticDataLoader1D);
+}
diff --git a/GUI/DataLoaders/DataLoaderUtil.h b/GUI/DataLoaders/DataLoaderUtil.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd075533c6843f8f624455fefddce96c29cfae2d
--- /dev/null
+++ b/GUI/DataLoaders/DataLoaderUtil.h
@@ -0,0 +1,27 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      GUI/DataLoaders/UserDefinedDataLoader1D.h
+//! @brief     Utility functions for data loaders
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2021
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+//  ************************************************************************************************
+
+#ifndef BORNAGAIN_GUI_DATALOADERS_DATALOADERUTIL_H
+#define BORNAGAIN_GUI_DATALOADERS_DATALOADERUTIL_H
+
+class AbstractDataLoader1D;
+class QString;
+
+//! clones the loader as a user defined loader and puts it in DataLoaders1D store
+void cloneAsUserDefinedLoader(AbstractDataLoader1D* loader, const QString& name);
+
+//! register the concrete 1D data loaders with DataLoaders1D
+void register1DDataLoaders();
+
+#endif // BORNAGAIN_GUI_DATALOADERS_DATALOADERUTIL_H
diff --git a/GUI/DataLoaders/DataLoaders1D.cpp b/GUI/DataLoaders/DataLoaders1D.cpp
deleted file mode 100644
index c4635fda26b65c2149546ec40a252a04725d32b6..0000000000000000000000000000000000000000
--- a/GUI/DataLoaders/DataLoaders1D.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/DataLoaders/DataLoaders1D.cpp
-//! @brief     Implements class DataLoaders1D
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2021
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#include "GUI/DataLoaders/DataLoaders1D.h"
-#include "GUI/DataLoaders/AutomaticDataLoader1D.h"
-#include "GUI/DataLoaders/QREDataLoader.h"
-#include "GUI/DataLoaders/UserDefinedDataLoader1D.h"
-
-namespace {
-
-// the one and only instance of DataLoaders1D
-DataLoaders1D dataLoaders1D;
-
-} // namespace
-
-DataLoaders1D* DataLoaders1D::m_instance = nullptr;
-
-DataLoaders1D::DataLoaders1D()
-{
-    m_instance = this;
-}
-
-DataLoaders1D::~DataLoaders1D()
-{
-    qDeleteAll(m_builtInLoaders);
-    qDeleteAll(m_userDefinedLoaders);
-}
-
-DataLoaders1D& DataLoaders1D::instance()
-{
-    return *m_instance;
-}
-
-void DataLoaders1D::initBuiltInLoaders()
-{
-    // the ordering in here defines the ordering in the selection combo box in the open file dialog
-    // and also in the selection combo box on the format configuration page. Furthermore the first
-    // returned loader will be used as default in the open file dialog if it is started for the
-    // first time
-    m_builtInLoaders << new QREDataLoader();
-    m_builtInLoaders << new AutomaticDataLoader1D();
-}
-
-QVector<AbstractDataLoader*> DataLoaders1D::loaders() const
-{
-    if (m_builtInLoaders.isEmpty())
-        const_cast<DataLoaders1D*>(this)->initBuiltInLoaders();
-    return m_builtInLoaders + m_userDefinedLoaders;
-}
-
-QVector<AbstractDataLoader*> DataLoaders1D::recentlyUsedLoaders() const
-{
-    return m_recentlyUsedLoaders;
-}
-
-void DataLoaders1D::cloneAsUserDefinedLoader(AbstractDataLoader* loader, const QString& name)
-{
-    loader->applyImportSettings();
-    auto clonedLoader = dynamic_cast<AbstractDataLoader1D*>(loader->clone());
-    const auto defaultProperties = loader->serialize();
-
-    m_userDefinedLoaders << new UserDefinedDataLoader1D(clonedLoader, name, defaultProperties);
-}
-
-AbstractDataLoader1D* DataLoaders1D::createFromPersistentName(const QString& persistentClassName)
-{
-    if (persistentClassName == AutomaticDataLoader1D().persistentClassName())
-        return new AutomaticDataLoader1D();
-
-    if (persistentClassName == QREDataLoader().persistentClassName())
-        return new QREDataLoader();
-
-    return nullptr;
-}
diff --git a/GUI/DataLoaders/QREDataLoader.h b/GUI/DataLoaders/QREDataLoader.h
index 588e89affb20ea5f917bf91ff834926e1e258a29..2429371c350b8197610365b390f8fc4748489245 100644
--- a/GUI/DataLoaders/QREDataLoader.h
+++ b/GUI/DataLoaders/QREDataLoader.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_DATALOADERS_QREDATALOADER_H
 #define BORNAGAIN_GUI_DATALOADERS_QREDATALOADER_H
 
-#include "GUI/DataLoaders/AbstractDataLoader1D.h"
+#include "GUI/Models/AbstractDataLoader1D.h"
 #include <QVector>
 #include <variant>
 
diff --git a/GUI/DataLoaders/QREDataLoaderResultModel.h b/GUI/DataLoaders/QREDataLoaderResultModel.h
index bda411d3851682f69933fad4873d932c5b8c15f2..6f5bca9ceb03c373c1f1ed8c5924607c8e3c38e6 100644
--- a/GUI/DataLoaders/QREDataLoaderResultModel.h
+++ b/GUI/DataLoaders/QREDataLoaderResultModel.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_DATALOADERS_QREDATALOADERRESULTMODEL_H
 #define BORNAGAIN_GUI_DATALOADERS_QREDATALOADERRESULTMODEL_H
 
-#include "GUI/DataLoaders/AbstractDataLoaderResultModel.h"
+#include "GUI/Models/AbstractDataLoaderResultModel.h"
 #include "GUI/DataLoaders/QREDataLoader.h"
 
 //! The result model of a QREDataLoader (for showing the import results in a table view).
diff --git a/GUI/DataLoaders/UserDefinedDataLoader1D.h b/GUI/DataLoaders/UserDefinedDataLoader1D.h
index 0f6d511c0b24458369e223c808e9f92de1a3819e..ffe553e92253956644cd673d4dee2cda6635cf95 100644
--- a/GUI/DataLoaders/UserDefinedDataLoader1D.h
+++ b/GUI/DataLoaders/UserDefinedDataLoader1D.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_DATALOADERS_USERDEFINEDDATALOADER1D_H
 #define BORNAGAIN_GUI_DATALOADERS_USERDEFINEDDATALOADER1D_H
 
-#include "GUI/DataLoaders/AbstractDataLoader1D.h"
+#include "GUI/Models/AbstractDataLoader1D.h"
 
 //! A user defined data loader. This is a thin wrapper around the real loader implementation,
 //! storing the relevant settings to make it user definable (namely name and import settings).
diff --git a/GUI/DataLoaders/AbstractDataLoader.cpp b/GUI/Models/AbstractDataLoader.cpp
similarity index 91%
rename from GUI/DataLoaders/AbstractDataLoader.cpp
rename to GUI/Models/AbstractDataLoader.cpp
index 1b848a8c3cf12e6d46de8b62eb3e2eb7b0c0c5aa..5a2e1e480b5a4706e99674573b805fcb25ffb650 100644
--- a/GUI/DataLoaders/AbstractDataLoader.cpp
+++ b/GUI/Models/AbstractDataLoader.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/DataLoaders/AbstractDataLoader.cpp
+//! @file      GUI/Models/AbstractDataLoader.cpp
 //! @brief     Implements class AbstractDataLoader
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/DataLoaders/AbstractDataLoader.h"
+#include "GUI/Models/AbstractDataLoader.h"
 #include <QString>
 
 void AbstractDataLoader::populateImportSettingsWidget(QWidget*) {}
diff --git a/GUI/DataLoaders/AbstractDataLoader.h b/GUI/Models/AbstractDataLoader.h
similarity index 95%
rename from GUI/DataLoaders/AbstractDataLoader.h
rename to GUI/Models/AbstractDataLoader.h
index 1cba670a18d480639b3b12f7110872d23b53d0be..0fec8f288e454f408ef4aaf9e771e5cb2a8ddaf7 100644
--- a/GUI/DataLoaders/AbstractDataLoader.h
+++ b/GUI/Models/AbstractDataLoader.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/DataLoaders/AbstractDataLoader.h
+//! @file      GUI/Models/AbstractDataLoader.h
 //! @brief     Defines class AbstractDataLoader
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADER_H
-#define BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADER_H
+#ifndef BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADER_H
+#define BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADER_H
 
 class QString;
 class QByteArray;
@@ -127,4 +127,4 @@ protected:
 QDataStream& operator<<(QDataStream& stream, const AbstractDataLoader& s);
 QDataStream& operator>>(QDataStream& stream, AbstractDataLoader& s);
 
-#endif // BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADER_H
+#endif // BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADER_H
diff --git a/GUI/DataLoaders/AbstractDataLoader1D.h b/GUI/Models/AbstractDataLoader1D.h
similarity index 71%
rename from GUI/DataLoaders/AbstractDataLoader1D.h
rename to GUI/Models/AbstractDataLoader1D.h
index c734918ed97ca99e29061144921fc1bbcc85fda3..83a1f77933247dc7f9c74d436e8843028086f3be 100644
--- a/GUI/DataLoaders/AbstractDataLoader1D.h
+++ b/GUI/Models/AbstractDataLoader1D.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/DataLoaders/AbstractDataLoader1D.h
+//! @file      GUI/Models/AbstractDataLoader1D.h
 //! @brief     Defines class AbstractDataLoader1D
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,14 +12,14 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADER1D_H
-#define BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADER1D_H
+#ifndef BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADER1D_H
+#define BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADER1D_H
 
-#include "GUI/DataLoaders/AbstractDataLoader.h"
+#include "GUI/Models/AbstractDataLoader.h"
 
 //! Abstract base class for reflectometry data loaders.
 
 class AbstractDataLoader1D : public AbstractDataLoader {
 };
 
-#endif // BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADER1D_H
+#endif // BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADER1D_H
diff --git a/GUI/DataLoaders/AbstractDataLoaderResultModel.cpp b/GUI/Models/AbstractDataLoaderResultModel.cpp
similarity index 95%
rename from GUI/DataLoaders/AbstractDataLoaderResultModel.cpp
rename to GUI/Models/AbstractDataLoaderResultModel.cpp
index ee4e54b5e1022737115dcc83002491630d0fa3b6..7c92ca367159d684c3f21574d66d46a055fca45f 100644
--- a/GUI/DataLoaders/AbstractDataLoaderResultModel.cpp
+++ b/GUI/Models/AbstractDataLoaderResultModel.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/DataLoaders/AbstractDataLoaderResultModel.cpp
+//! @file      GUI/Models/AbstractDataLoaderResultModel.cpp
 //! @brief     Implements class AbstractDataLoaderResultModel
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/DataLoaders/AbstractDataLoaderResultModel.h"
+#include "GUI/Models/AbstractDataLoaderResultModel.h"
 #include <QColor>
 #include <QIcon>
 #include <QVariant>
diff --git a/GUI/DataLoaders/AbstractDataLoaderResultModel.h b/GUI/Models/AbstractDataLoaderResultModel.h
similarity index 94%
rename from GUI/DataLoaders/AbstractDataLoaderResultModel.h
rename to GUI/Models/AbstractDataLoaderResultModel.h
index 9f948a984553f66e0646858fc2b563405b96f450..12624f0ae047039889c400e6a1f2ef0623475628 100644
--- a/GUI/DataLoaders/AbstractDataLoaderResultModel.h
+++ b/GUI/Models/AbstractDataLoaderResultModel.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/DataLoaders/AbstractDataLoaderResultModel.h
+//! @file      GUI/Models/AbstractDataLoaderResultModel.h
 //! @brief     Defines class AbstractDataLoaderResultModel
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADERRESULTMODEL_H
-#define BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADERRESULTMODEL_H
+#ifndef BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADERRESULTMODEL_H
+#define BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADERRESULTMODEL_H
 
 #include <QAbstractItemModel>
 #include <QIcon>
@@ -93,4 +93,4 @@ private:
     QIcon m_warningIcon;
 };
 
-#endif // BORNAGAIN_GUI_DATALOADERS_ABSTRACTDATALOADERRESULTMODEL_H
+#endif // BORNAGAIN_GUI_MODELS_ABSTRACTDATALOADERRESULTMODEL_H
diff --git a/GUI/Models/DataLoaders1D.cpp b/GUI/Models/DataLoaders1D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..16f6e8a13096347561c03f82a640351bd60a1c34
--- /dev/null
+++ b/GUI/Models/DataLoaders1D.cpp
@@ -0,0 +1,62 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      GUI/Models/DataLoaders1D.cpp
+//! @brief     Implements class DataLoaders1D
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2021
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+//  ************************************************************************************************
+
+#include "GUI/Models/DataLoaders1D.h"
+#include "GUI/Models/AbstractDataLoader1D.h"
+
+DataLoaders1D::~DataLoaders1D()
+{
+    qDeleteAll(m_builtInLoaders);
+    qDeleteAll(m_userDefinedLoaders);
+}
+
+DataLoaders1D& DataLoaders1D::instance()
+{
+    static DataLoaders1D inst;
+
+    return inst;
+}
+
+void DataLoaders1D::addBuiltInLoader(const QString& name, 
+                                     const std::function<AbstractDataLoader1D*()>& create)
+{
+    m_createLoaders.emplace(name, create);
+    m_builtInLoaders.push_back(create());
+}
+
+void DataLoaders1D::addUserDefinedLoader(AbstractDataLoader1D* loader)
+{
+    m_userDefinedLoaders.push_back(loader);
+}
+
+QVector<AbstractDataLoader1D*> DataLoaders1D::loaders() const
+{
+    return m_builtInLoaders + m_userDefinedLoaders;
+}
+
+QVector<AbstractDataLoader1D*> DataLoaders1D::recentlyUsedLoaders() const
+{
+    return m_recentlyUsedLoaders;
+}
+
+AbstractDataLoader1D* DataLoaders1D::createFromPersistentName(const QString& persistentClassName)
+{
+    std::map<QString,std::function<AbstractDataLoader1D*()>>::const_iterator it =
+        m_createLoaders.find(persistentClassName);
+
+    if (it != m_createLoaders.end())
+        return it->second();
+    else
+        return nullptr;
+}
diff --git a/GUI/DataLoaders/DataLoaders1D.h b/GUI/Models/DataLoaders1D.h
similarity index 57%
rename from GUI/DataLoaders/DataLoaders1D.h
rename to GUI/Models/DataLoaders1D.h
index f818f3b9aec8d9d727ae085865e7849c4e55ee91..e9a51de1afe9998954e617b82bb274c18bd87a11 100644
--- a/GUI/DataLoaders/DataLoaders1D.h
+++ b/GUI/Models/DataLoaders1D.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      GUI/DataLoaders/DataLoaders1D.h
+//! @file      GUI/Models/DataLoaders1D.h
 //! @brief     Defines class DataLoaders1D
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,51 +12,57 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_DATALOADERS_DATALOADERS1D_H
-#define BORNAGAIN_GUI_DATALOADERS_DATALOADERS1D_H
+#ifndef BORNAGAIN_GUI_MODELS_DATALOADERS1D_H
+#define BORNAGAIN_GUI_MODELS_DATALOADERS1D_H
 
 #include <QVector>
 
-class AbstractDataLoader;
+#include <map>
+#include <functional>
+
 class AbstractDataLoader1D;
 
 //! Collection of all available data loaders for 1D files
 
 class DataLoaders1D {
 public:
-    DataLoaders1D();
     ~DataLoaders1D();
 
     //! The one and only instance
     static DataLoaders1D& instance();
 
+    //! Register a built-in loader with the given class name and factory function
+    void addBuiltInLoader(const QString& persistentClassName,
+                          const std::function<AbstractDataLoader1D*()>& create);
+
+    //! add a user defined loader
+    void addUserDefinedLoader(AbstractDataLoader1D* loader);
+
     //! all defined loaders. A null element in the list defines a separator
     //! The returned pointers are the same over the lifetime of the DataLoaders instance, therefore
     //! they can be used for comparison.
-    QVector<AbstractDataLoader*> loaders() const;
+    QVector<AbstractDataLoader1D*> loaders() const;
 
     //! The last 10 recently used loaders.
-    QVector<AbstractDataLoader*> recentlyUsedLoaders() const;
+    QVector<AbstractDataLoader1D*> recentlyUsedLoaders() const;
 
     //! Notify loader was recently used
-    void setRecentlyUsedLoader(const AbstractDataLoader* loader);
-
-    //! Clone the loader and create a user defined loader with its current settings and the given
-    //! name
-    void cloneAsUserDefinedLoader(AbstractDataLoader* loader, const QString& name);
+    //void setRecentlyUsedLoader(const AbstractDataLoader1D* loader);
 
     //! Create loader from the given persistent name
     AbstractDataLoader1D* createFromPersistentName(const QString& persistentClassName);
 
 private:
+    DataLoaders1D() = default;
+
     //! create all default built in loaders
     void initBuiltInLoaders();
 
 private:
-    static DataLoaders1D* m_instance;
-    QVector<AbstractDataLoader*> m_builtInLoaders;
-    QVector<AbstractDataLoader*> m_recentlyUsedLoaders;
-    QVector<AbstractDataLoader*> m_userDefinedLoaders;
+    QVector<AbstractDataLoader1D*> m_builtInLoaders;
+    QVector<AbstractDataLoader1D*> m_recentlyUsedLoaders;
+    QVector<AbstractDataLoader1D*> m_userDefinedLoaders;
+    std::map<QString,std::function<AbstractDataLoader1D*()>> m_createLoaders;
 };
 
-#endif // BORNAGAIN_GUI_DATALOADERS_DATALOADERS1D_H
+#endif // BORNAGAIN_GUI_MODELS_DATALOADERS1D_H
diff --git a/GUI/Models/RealDataItem.cpp b/GUI/Models/RealDataItem.cpp
index 669e3756029598ae672b5e9e855b62672b924f62..9c84e43fe8cb0af471cfe106ac6e7fd22300847b 100644
--- a/GUI/Models/RealDataItem.cpp
+++ b/GUI/Models/RealDataItem.cpp
@@ -14,8 +14,8 @@
 
 #include "GUI/Models/RealDataItem.h"
 #include "Device/Data/DataUtils.h"
-#include "GUI/DataLoaders/AbstractDataLoader1D.h"
-#include "GUI/DataLoaders/DataLoaders1D.h"
+#include "GUI/Models/AbstractDataLoader1D.h"
+#include "GUI/Models/DataLoaders1D.h"
 #include "GUI/Models/Error.h"
 #include "GUI/Models/ImportDataInfo.h"
 #include "GUI/Models/InstrumentItems.h"
diff --git a/GUI/Models/RealDataItem.h b/GUI/Models/RealDataItem.h
index 795c23e9afc17c782d271e2a4d2c3676f3ae46d9..3e9ded5309eb500ac22a161b579467e3b0e6c3e4 100644
--- a/GUI/Models/RealDataItem.h
+++ b/GUI/Models/RealDataItem.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_MODELS_REALDATAITEM_H
 #define BORNAGAIN_GUI_MODELS_REALDATAITEM_H
 
-#include "GUI/DataLoaders/AbstractDataLoader.h"
+#include "GUI/Models/AbstractDataLoader.h"
 #include "GUI/Models/SessionItem.h"
 #include <QPointer>
 
diff --git a/GUI/Views/ImportDataWidgets/RealDataSelectorWidget.cpp b/GUI/Views/ImportDataWidgets/RealDataSelectorWidget.cpp
index ef8531bc929fd3d3b4cc4a4b134384b7d9ef4d48..5ab540b0a8d908bf79a58886ccd6b557af73d6f9 100644
--- a/GUI/Views/ImportDataWidgets/RealDataSelectorWidget.cpp
+++ b/GUI/Views/ImportDataWidgets/RealDataSelectorWidget.cpp
@@ -15,7 +15,8 @@
 #include "GUI/Views/ImportDataWidgets/RealDataSelectorWidget.h"
 #include "Device/Data/DataUtils.h"
 #include "GUI/Application/Application.h"
-#include "GUI/DataLoaders/DataLoaders1D.h"
+#include "GUI/Models/AbstractDataLoader1D.h"
+#include "GUI/Models/DataLoaders1D.h"
 #include "GUI/Models/Error.h"
 #include "GUI/Models/RealDataItem.h"
 #include "GUI/Views/CommonWidgets/GUIHelpers.h"
@@ -203,7 +204,7 @@ void RealDataSelectorWidget::onContextMenuRequest(const QPoint& point)
 
 void RealDataSelectorWidget::importData1D()
 {
-    QMap<QString, AbstractDataLoader*> loaderOfFilter;
+    QMap<QString, AbstractDataLoader1D*> loaderOfFilter;
     QString filters;
     for (auto loader : DataLoaders1D::instance().loaders()) {
         const QString filter =
diff --git a/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.cpp b/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.cpp
index 2146996ff8a7870735904a50e824987038c2395c..567b66cf33eaaf90dd63ef31cdb2ea84ae976c1c 100644
--- a/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.cpp
+++ b/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.cpp
@@ -13,9 +13,10 @@
 //  ************************************************************************************************
 
 #include "GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.h"
-#include "GUI/DataLoaders/AbstractDataLoaderResultModel.h"
-#include "GUI/DataLoaders/DataLoaders1D.h"
+#include "GUI/DataLoaders/DataLoaderUtil.h"
+#include "GUI/Models/AbstractDataLoaderResultModel.h"
 #include "GUI/Models/DataItemUtils.h"
+#include "GUI/Models/DataLoaders1D.h"
 #include "GUI/Models/InstrumentItems.h"
 #include "GUI/Models/RealDataItem.h"
 #include "GUI/Models/SpecularDataItem.h"
@@ -333,7 +334,7 @@ void SpecularDataImportWidget::onCreateNewFormatButton()
     if (!ok || name.isEmpty())
         return;
 
-    DataLoaders1D::instance().cloneAsUserDefinedLoader(m_loader, name);
+    cloneAsUserDefinedLoader(m_loader, name);
 
     fillLoaderCombo();
     m_ui->formatSelectionComboBox->setCurrentText(name);
diff --git a/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.h b/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.h
index 5c3e5defd6b7475b5f72051665631aee081dccec..fd1074638be654175dad8603616544f322a7bd97 100644
--- a/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.h
+++ b/GUI/Views/SpecularDataWidgets/SpecularDataImportWidget.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_VIEWS_SPECULARDATAWIDGETS_SPECULARDATAIMPORTWIDGET_H
 #define BORNAGAIN_GUI_VIEWS_SPECULARDATAWIDGETS_SPECULARDATAIMPORTWIDGET_H
 
-#include "GUI/DataLoaders/AbstractDataLoader1D.h"
+#include "GUI/Models/AbstractDataLoader1D.h"
 #include "GUI/Views/CommonWidgets/SessionItemWidget.h"
 #include "qcustomplot.h"
 #include <memory>
diff --git a/GUI/main/main.cpp b/GUI/main/main.cpp
index 0f2ddbb33005abacdaf8b3b4c17952399413858d..2fc554eea5cdab5c575298e90ff4335f7b10bb28 100644
--- a/GUI/main/main.cpp
+++ b/GUI/main/main.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/Application/Application.h"
+#include "GUI/DataLoaders/DataLoaderUtil.h"
 #include "GUI/main/MessageHandler.h"
 #include "GUI/main/appoptions.h"
 #include "GUI/mainwindow/mainwindow.h"
@@ -37,6 +38,8 @@ int main(int argc, char* argv[])
 
     qInstallMessageHandler(MessageHandler);
 
+    register1DDataLoaders();
+
     MainWindow win;
     if (options.find("geometry"))
         win.resize(options.mainWindowSize());