Надежный способ получить тип класса из службы, созданный с помощью .Net Core DI - PullRequest
0 голосов
/ 07 октября 2019

По сути, я хочу иметь возможность определять пространство имен класса вызывающего абонента внутри моего сервиса. Создание экземпляра службы происходит со стандартным DI ASP.NET Core. Еще одно препятствие может возникнуть из-за того, что я хочу определить вызывающего в конструкторе базового класса, а не непосредственно в экземпляре службы.

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

Редактировать

Пример кода

// First caller
namespace Example.Assembly.One
{
    public class CallerOne
    {
        consctructor(Service service)

        void WhichCallerAmI() { return this.service.ReturnCaller() }
        ...
    }   
}

// Second caller
namespace Example.Assembly.Two
{
    public class CallerTwo
    {
        consctructor(Service service)

        void WhichCallerAmI() { return this.service.ReturnCaller() }
        ...
    }   
}


// Service
namespace Example.Service
{
    public class Service : BaseService
    {
        consctructor() : base()

        public void ReturnCaller()
        {
            if (this.namespace == "Example.Assembly.One")
            {
                return "First caller";
            }

            return "Second caller";
        }  
    }   
}

// Base service
namespace Example.Service
{
    public class BaseService
    {
        consctructor(Service service)
        {
            // Determine namespace of caller here
            this.namespace = <insert-answer-here>
        }
    }   
}

// demo
// These callers can be controllers or other services
var firstCaller = new CallerOne() 
var secondCaller = new CallerTwo();

// firstResult now contains "First Caller"
var firstResult = firstCaller.WhichCallerAmI();

// secondResult now contains "Second Caller";
var secondResult = secondCaller.WhichCallerAmI();

XY проблема

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

1 Ответ

2 голосов
/ 07 октября 2019

Итак, у вас есть класс:

public class Consumer
{
    public Consumer(Provider provider)
    {
        // ...
    }
}

И этот класс имеет следующую зависимость:

public class Provider : BaseProvider
{
    public Provider()
        : base()
    {
        // ...
    }
}

И эта зависимость имеет базовый класс:

public class BaseProvider
{
    public BaseProvider()
    {
        // ...
    }
}

А теперь в конструкторе BaseProvider вы хотите знать, для какого вызывающего абонента он инициализируется?

Вы не можете.

Каркас внедрения зависимостей будет инициализировать Provider service до создания класса Consumer. Таким образом, вы не сможете получить эту информацию, особенно не из трассировки стека.

Это проблема XY. Если вам нужно знать , кто вызывает класс, вы делаете что-то не так. То, что вы могли бы искать, - это параметризованный конструктор в Provider, который вызывается с различными параметрами в зависимости от того, кому он нужен, чтобы изменить его поведение. Но это совсем другой вопрос.

Для последнего см., Например, .NET Core DI, способы передачи параметров в конструктор .

...