Страницы

Поиск по вопросам

понедельник, 24 февраля 2020 г.

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

#c_sharp


Есть следующие типы в пространстве имен:

namespace Model {
   public interface IData {
      void Send(string str);
   }
   public class Test {
      public void Run() {
        // (1)
      }
   }
}


В методе Test.Run для его работы должна оказаться ссылка на объект с реализацией IData.

Есть следующая реализация интерфейса IData и код для работы с Test.

class Data : Model.IData {
    public void Send(string str) { }     
}     

var d = new Data();
var t = new Test();

// (2) 


Какой код должен быть вместо (1) и (2), чтобы в Test.Run оказалась ссылка на Data?
При этом в определении класса Test нельзя что-либо менять, нельзя добавлять конструктор(ы),
методы, свойства и поля, и нельзя менять сигнатуру метода Run.

Также нельзя использовать Singleton.

p.s.
Это не для "размять мозги", как сказали в комментах. Есть огромное количество кода.
И есть просто драконовский анализатор кода. Добавлять/менять правила в анализаторе
не будут. Код Model менять нельзя и синглтоны исключены, а в Test.Run надо добавить
зависимость. На вопрос, - как? Ответили, - как хотите так и делайте. 
Если есть идеи - напишите как, а не минусуйте вопрос.
    


Ответы

Ответ 1



Вот рабочий пример с thread local storage: namespace Model { public interface IData { void Send(string str); } public class Test { public void Run() { LocalDataStoreSlot slot = Thread.GetNamedDataSlot("dict"); var dict = (Dictionary)Thread.GetData(slot); var d = dict[this]; } } } namespace ThreadLocalTest { class Data : Model.IData { public void Send(string str) { } } class Program { static void Main(string[] args) { var d = new Data(); var t = new Model.Test(); LocalDataStoreSlot slot = Thread.AllocateNamedDataSlot("dict"); var dict = new Dictionary(); Thread.SetData(slot, dict); dict[t] = d; t.Run(); Thread.FreeNamedDataSlot("dict"); } } } По поводу других возможных опций, вот ещё: http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html (это пригодится, если вы хотите протащить контекст через границу await).

Ответ 2



В порядке дурацкого предложения. Создаём новый класс, который слушает сетевой порт. В конструктор передаём адрес объекта типа Data. В Test.Run подключаемся к порту и получаем адрес. Можно также использовать вместо сетевых соединений pipe или класть адрес в файл с фиксированным расположением.

Комментариев нет:

Отправить комментарий