Создание класса с интерфейсами в c # - PullRequest
0 голосов
/ 07 февраля 2019

Привет, это может быть тривиально, но я пытаюсь понять создание экземпляров класса с помощью интерфейса.Ниже приведен мой код:

public interface IRepository
{
    string GetMemberDisplayName();
}

public class Repository : IRepository
{
    private readonly Manager _manager;

    public Repository() {}

    public Repository(string connectionName)
    {
        _manager = new Manager(connectionName);
    }

    public string GetMemberDisplayName(string ID)
    {
        return "FooFoo";
    }
}

Теперь в другом классе, использующем функциональность класса репозитория, был создан его экземпляр следующим образом:

public class LogServiceHelper
{
    readonly IRepository _alrAttendance;
    readonly IRepository _alrUsers;

    public LogServiceHelper()
    {
        _alrAttendance = new Repository("value1");
        _alrUsers = new Repository("value2");
    }

    public string GetMemberName(string empId)
    {
        return _alrUsers.GetMemberDisplayName(empId);
    }
}

Мой вопрос заключается в том, является ли это правильным способом создания экземпляракласс с параметризованным конструктором.И если да, то второй вопрос - зачем нам интерфейс в этом случае.Мы могли бы напрямую создать экземпляр класса, не создавая интерфейс?

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Мы могли бы напрямую создать экземпляр класса, не создавая интерфейс?

Это действительно так и может работать без проблем.Но затем мы подходим к ключевым вопросам:

  • Можно ли проверить мой код, как бы я протестировал этот кусок кода?
  • Могу ли ялегко изменить поведение без изменения LogServiceHelper

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

public LogServiceHelper(IRepository alrAttendance, IRepository alrUsers)
{
    _alrAttendance = alrAttendance;
    _alrUsers = alrUsers;
}

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

0 голосов
/ 07 февраля 2019

Да, это как вызывать параметризованный конструктор, но нет, это не то, что вы должны делать.

Как вы понимаете, LogServiceHelper имеет жесткую зависимость от класса Repository, итак что вы правы, интерфейсы ничего вам не покупают.Однако, если им вводили :

public LogServiceHelper(IRepository attendanceRepo, IRepository userRepo)
{
    _alrAttendance = attendanceRepo;
    _alrUsers = userRepo;
}

Вы внезапно получаете преимущества абстракции.Примечательно, что модульный тест может проходить в поддельных репозиториях и что вы можете переключиться на другую реализацию IRepository без изменения LogServiceHelper.

Следующий вопрос: «Кто создает конкретный класс Repository?».Для этого я отсылаю вас к различным контейнерам DI / IoC, таким как Autofac, Unity и NInject.

...