Внедрение зависимости C# - как Вам вводят зависимость без источника?

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

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

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

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

5
задан Ian Ringrose 18 October 2010 в 12:53
поделиться

3 ответа

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

public class TheirClass
{
  public void DoSomething();
}

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

public interface ITheirClass
{
  void DoSomething();
}

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

public class TheirClassWrapper : TheirClass, ITheirClass
{

}

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

public class TheirClassWrapper : ITheirClass
{
  private TheirClass instance = new TheirClass();

  public void DoSomething()
  {
    instance.DoSomething();
  }
}

Тогда вы можете инжектировать этот интерфейс вместо него.

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

6
ответ дан 14 December 2019 в 08:42
поделиться

Если у вас нет необходимости менять что-либо в классе, вам вряд ли понадобится этот код. Предположим, у вас есть класс 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.
0
ответ дан 14 December 2019 в 08:42
поделиться

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

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

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

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

public interface IMyNewInterface
{
    void Method1();
}

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

public class MyNewClass : IMyNewInterface
{
    private MyConcreteClass _MyConcreteClass;

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

    public void Method1()
    {
        _MyConcreteClass.Method1();
    }
}
1
ответ дан 14 December 2019 в 08:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: