Загрузка реализации на основе параметра - PullRequest
3 голосов
/ 18 февраля 2011

У меня есть эта проблема:

В C # я делаю программу, которая должна подключаться к различным базам данных (SQLite, SQL Server Compact, MS Access и т. Д.). Я установил в app.config параметр с именем «dbType» (это может быть 1 для SQLlite, 2 для SQL Server Compact, 3 для MS Access и т. Д.). Этот параметр должен быть изменен пользователем во время работы программы с выпадающим меню или чем-то вроде этого.

Затем программа считывает этот параметр и создает экземпляр реализации интерфейса базы данных (IDatabase), который соответствует выбранной базе данных.

Код:

class ObjectDatabaseCreator
    {
        protected ObjectDatabase objectDb;
        protected Object objectDAO;
        protected int dbType;
        protected String dbName;

        public ObjectDatabaseCreator()
        {
        }

        public ObjectDatabaseCreator(String dbName)
        {
            this.dbType = ObjectConfiguration.getDbType();
            this.dbName = dbName;
        }

        public ObjectDatabase getObjectDatabase()
        {
            //1 - SQLite; 2-SQLServer Compact; 3-SQLServer Express; 4-MS Access


            switch (dbType)
            {


                case 1:
                    objectDb = new ObjectDatabase(new Database_Impl_1(dbName));
                    break;

                case 2:
                    objectDb = new ObjectDatabase(new Database_Impl_2(dbName));
                    break;

                case 3:
                    objectDb = new ObjectDatabase(new Database_Impl_3(dbName));
                    break;

                case 4:
                    objectDb = new ObjectDatabase(new Database_Impl_4(dbName));
                    break;
            }

            return objectDb;
        }   

    }

Что ж, похоже, это работает, но я хотел бы знать, есть ли возможность упростить добавление других баз данных, я имею в виду, если будет другая база данных, я должен изменить этот класс, перекомпилировать и т. Д.

И как я мог бы создать другую реализацию для классов BLL, скажем, Person, Customer и т. Д.? Они также меняются, и я должен добавить больше классов.

Спасибо, Трав

Ответы [ 4 ]

1 голос
/ 18 февраля 2011

взгляните на MEF ... это может быть полезно, поскольку добавляет понятие каталога.Определяет столько классов IDataBaseImplemention, сколько вы хотите в сборках, расположенных в папке, и MEF позволит вам «импортировать» все найденные классы.

MEF включен в .Net framework (из V4), но естьЕсть много других фреймворков, которые могут сделать эту работу.

0 голосов
/ 18 февраля 2011

Самый общий способ сделать это - заставить пользователя указать квалифицированное имя сборки типа, который должен быть загружен. Вы можете создать экземпляр объекта по имени типа, используя что-то вроде этого:

IDatabase GetDatabase(string typeName)
{
    var databaseType = Type.GetType(typeName);
    if (databaseType == null)
    {
        return null;
    }
    return (IDatabase)Activator.CreateInstance(databaseType);
}

Затем пользователи могут указать практически любую реализацию IDatabase, включая те, которые содержатся в предоставленных пользователем сборках:

IDatabase db = GetDatabase("EnterpriseLib.XmlDatabase, EnterpriseLib.XmlDatabase, Version=1.42.0.0, Culture=neutral, PublicKeyToken=AAAAAAAAAAAAAAAA"");

Это должно работать, пока сборка содержится в одной из папок в пути поиска сборки.

0 голосов
/ 18 февраля 2011

Вы можете добавить карту из целочисленного значения в тип класса. Примерно так (не проверено):

// initialization somewhere:
Dictionary<int,Type> databases = new Dictionary<int,Type>();
databases.Add(1, Database_Impl_1);
databases.Add(2, Database_Impl_2);
// ...
// then later, in getObjectDatabase()
objectDb = new ObjectDatabase(databases[settingValue]);

Google инверсия контроля - для этого есть рамки.

0 голосов
/ 18 февраля 2011

Я думаю, что с вашим дизайном что-то не так, если бизнес-классы меняются в зависимости от используемого движка базы данных. Поэтому я предлагаю нормализовать ваши бизнес-классы.

Что касается соединений с базой данных, вы должны использовать DbProviderFactories, DbProviderFactory, DbConnection и т. Д. Из пространства сборки / имени System.Data.Common http://msdn.microsoft.com/en-us/library/9tahwysy.aspx

вместе с разделом connectionString файла конфигурации, если вы хотите сделать это правильно. http://msdn.microsoft.com/en-us/library/ms178411(v=VS.85).aspx

Если вы хотите просто улучшить текущую реализацию, используйте фабрики как для объекта базы данных, так и для бизнес-объектов. Но на самом деле со временем это станет еще большей проблемой.

...