C # внедрение зависимости - как вам внедрить зависимость без источника? - PullRequest
5 голосов
/ 17 июня 2010

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

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

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

Надеюсь, это имеет смысл, спасибо.

Ответы [ 3 ]

6 голосов
/ 17 июня 2010

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

public class TheirClass
{
  public void DoSomething();
}

С помощью которого вы можете определить интерфейс:

public interface ITheirClass
{
  void DoSomething();
}

И реализовать этот интерфейс в классе-оболочке:

public class TheirClassWrapper : TheirClass, ITheirClass
{

}

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

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

1 голос
/ 17 июня 2010

Вопрос в том, почему вы хотите внедрить его как интерфейс?Это потому, что класс реализует некоторые свойства / методы, которые вы хотели бы абстрагировать, чтобы его можно было заменить, или вы просто пытаетесь «навязать» ему интерфейс маркера, потому что «мы всегда зависим от интерфейсов, а не от конкретных классов»?Если это последний, то вы на неправильном пути, так как вы, вероятно, в любом случае просто бросили бы его к бетону.

Предполагая, что у первого из двух я вижу два варианта:

  1. Вместо этого используйте наследование.Это может или не может быть возможным в зависимости от того, какой класс был создан, но вы можете унаследовать его и заменить свой новый класс старым.
  2. Создайте интерфейс самостоятельно, с нужными вам методами / свойствами иобернуть внешний конкретный класс в класс, который реализует интерфейс.

Для варианта 2, если вы не можете наследовать, например, если вы заботитесь только об одном методе в классе (мы назовем его Method1 ()), вы создадите соответствующий интерфейс дляit:

public interface IMyNewInterface
{
    void Method1();
}

Затем создайте его реализацию, которая принимает конкретный класс в качестве зависимости (вводимой вашим контейнером как обычно), которая просто вызывает конкретный класс:

public class MyNewClass : IMyNewInterface
{
    private MyConcreteClass _MyConcreteClass;

    public void MyNewClass(MyConcreteClass concreteClass)
    {
        _MyConcreteClass = concreteClass;
    }

    public void Method1()
    {
        _MyConcreteClass.Method1();
    }
}
0 голосов
/ 17 июня 2010

Если у вас нет необходимости что-либо менять в классе, вам вряд ли понадобится код.Предположим, у вас есть класс X в DLL, который вы хотите внедрить в другой класс Y, который вы пишете.В таком случае вы можете создать экземпляр X и поместить его в качестве параметра в конструктор Y. Это будет выглядеть примерно так:

Добавьте ссылку на DLL, содержащую класс X, в вашем проекте.

Use NameSpaceOfX;
Class Y
{
    Public Y() //Default constructor
    {
    }

    Public Y(X instanceOfX)
    {
        //Use instanceOfX here as required
    }
}

У вас основной код:

//Create instance of X
X instanceOfX = new X();
//Inject it into Y
Y instanceOfY = new Y(instanceOfX);
//Use Y now.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...