2016-09-06 6 views
0

Я создал и интерфейс IDataProvider и реализовать это следующим образом:Как улучшить инъекцию зависимости?

public class DatabaseDataProviderBase : IDataProvider 
{ 
    private readonly IDatabaseConnectionStringProvider _databaseConnectionStringProvider; 
    private readonly IParameterApplicator<string> _sqlParameterApplicator; 
    private readonly IDatabaseDataProvider _databaseDataProvider; 

    public DatabaseDataProviderBase(IDatabaseConnectionStringProvider databaseConnectionStringProvider, IParameterApplicator<string> sqlParameterApplicator, IDatabaseDataProvider databaseDataProvider) 
    { 
     _databaseConnectionStringProvider = databaseConnectionStringProvider; 
     _sqlParameterApplicator = sqlParameterApplicator; 
     _databaseDataProvider = databaseDataProvider; 
    } 

    public DataSet GetData(SqlResource sqlResource, List<Parameter> parameters) 
    { 
     var connectionString = _databaseConnectionStringProvider.Get(sqlResource.SqlConnection); 
     var selectQuery = _sqlParameterApplicator.Apply(parameters, sqlResource.SelectQuery); 
     var dataSet = _databaseDataProvider.Get(connectionString, selectQuery); 

     return dataSet; 
    } 
} 

Теперь мне нужно будет много классов, которые наследуют от этого класса. А именно, NpgsqlDataProvider, MsSqlDataProvider, OdbcDataprovider и более. Каждый из этих классов будет иметь свои собственные реализации IDatabaseConnectionStringProvider и IDatabaseDataProvider. Я расскажу, какую реализацию использовать, привязывая их в модуле Ninject.

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

Однако унаследованные классы просто пусты - они используют этот базовый класс DatabaseDataProviderBase, и из-за этого я чувствую, что я сделал что-то неправильно. Совет оценил.

ответ

0

Вам не нужны производные классы только ради полноты. Ваш базовый класс уже завершен.

Дело в том, как вы собираетесь использовать класс. Вы просто собираетесь использовать IDataProvider?

IDataProvider consumer = new ... 

Если это так, то проблема может заключаться в том, чтобы ввести поставщика данных. Вы можете использовать завод для этой цели, и сделать с ней:

void Consumer(Func<IDataProvider> providerFactory) 
{ 
    IDataProvider provider = providerFactory(); 
    ... 
} 

Таким образом, вы просто должны заполнить завод поставщика для всех потребляющих классов и позволить им использовать абстрактную поставщику данных. Вам не нужны производные классы, если вы способны предоставить один делегат Func<IDataProvider> или другой.

+0

Я хотел бы ввести «IDataProvider» в потребитель, используя инъекцию конструктора. Однако, если я не буду иметь производные классы и не укажу конкретную привязку в модуле ninject, как базовый класс будет знать, какую реализацию «IDatabaseConnectionStringProvider», например, использовать? –

+0

Но поставщик строки подключения является аргументом конструктора поставщика данных. Потребителю это не нужно знать. Ninject поддерживает более тонкую настройку. Вы можете обратиться к своей документации за подробностями: https://github.com/ninject/Ninject/wiki/Contextual-Binding –

 Смежные вопросы

  • Нет связанных вопросов^_^