Внедрение зависимостей с интерфейсом, но конструктору требуется строковый параметр - PullRequest
0 голосов
/ 28 января 2019

У меня есть класс репозитория, в котором есть конструктор с аргументом строкового параметра.Это строка подключения.Я создал для него интерфейс, и я использую Unity в своем проекте пользовательского интерфейса.

Мой вопрос состоит в том, как мне установить «правильный» способ, чтобы Unity знала, как правильно построить мой класс вЧтобы внедрить его при создании экземпляра моего контроллера?

В настоящее время я «обошел» это, используя конструктор без параметров для своего хранилища, но чувствую, что это коп.

Вот мой конструктор хранилищаЯ хочу использовать ...

    public CobraLettersRepository(string dbConnectionString)
    {
        _connString = dbConnectionString ?? throw new ArgumentNullException(dbConnectionString);

        dbConnection = new SqlConnection(_connString);
        dbConnection.Open();
    }

Я создал ICobraLettersRepository и хочу внедрить его в конструктор моего контроллера.

    public CobraLetterController(ICobraLetterRepository cobraLetterRepository)
    {
        if (cobraLetterRepository == null)
            throw new ArgumentNullException(cobraLetterRepository);

        _cobraLetterRepo = cobraLetterRepository;
    }

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

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Я бы сказал, чтобы инкапсулировать строку подключения внутри объекта конфигурации и поместить get строки подключения в конструктор этого объекта конфигурации.Затем просто зарегистрируйте свой объект конфигурации как другой класс.

public class ProjectConfiguration
{
    public string ConnectionString { get; set; }

    public ProjectConfiguration()
    {
        ConnectionString = //Get the configuration from , i.e: ConfigurationManager
    }

}

И затем введите его:

public CobraLettersRepository(ProjectConfiguration configuration)
{
    if(configuration == null){
        throw new ArgumentNullException(configuration);
    }
    _connString = configuration.ConnectionString;

    dbConnection = new SqlConnection(_connString);
    dbConnection.Open();
}

С этим вы всегда можете изолировать конфигурацию от контейнера DI и оставить инъекциютак просто, как вы можете.Кроме того, вы можете получить конфигурацию из ваших файлов конфигурации (по одному на среду).

РЕДАКТИРОВАТЬ: Также проверьте логику конструктора хранилища, может быть, вы не хотите, чтобы открыть соединение в конструкторе.Лучше сделать операторы using для методов вашего класса, например:

using(SqlConnection connection = new SqlConnection(_injectedConfiguration.ConnectionString)){
    connection.Open();
    //Make your stuff here
}

С помощью использования вы гарантируете правильное расположение соединения.

Обратите внимание, что при подходе объекта конфигурации вы можетепросто сохраните объект конфигурации в закрытой переменной только для чтения и используйте его как вам угодно.

0 голосов
/ 28 января 2019

Во время регистрации используйте InjectionConstructor для передачи имени строки подключения.Вам нужно удалить все конструкторы, кроме одного, который ожидает аргумент string.

container.RegisterType<ICobraLetterRepository,CobraLettersRepository>(new InjectionConstructor("connectionstringname"));

Обратите внимание, что это приведет к проблемам где-то / когда-нибудь.Вам нужно изменить логику для создания соединения с базой данных (вы можете ссылаться на Нарушение принципов SOLID в множественной реализации интерфейса или Разрешение именованной зависимости регистрации в Unity с параметром времени выполнения ).

...