Как вызвать метод из класса без ссылки

211
12 января 2019, 03:40

Есть приложение состоящее из библиотек классов, приложение WinForm в MVP немного исправленное под себя, + DI. Из View я передаю вызов в Presenter, где он обрабатывает его, и отправляет сначала в Service где перенаправляет в Infrasctructure, весь анализирующий код я хочу перенести в эту библиотеку. Проблема в том, что бы вернуть какие то значения, мне нужно вызвать метод из Presenter а я не могу создать ссылку на Presenter из Infrastructure так как это зациклит приложение, подскажите как можно решить эту проблему?

UPD CODE

Presenter.MainPresenter

class MainPresenter : IMainPresenter
{
    IBrService _br;
    public MainPresenter(IBrService br)
    {
      _br=br;
    }
    public void OnBrLoginClickEventRaised(object sender, EventArgs e)
    {
       _br.AuthorisationUser(Br.Default.Token);
    }
}

Service.BrService

public class BrService : IBrService
{
    private IBr _br;
    public BrService(IBr br)
    {
        _br = br;
    }
    public void AuthorisationUser(string token) => _br.AuthorisationUser(token);
}

Infrastructure.Br

public class Br : IBr
{
    public WebSocket _webSocketBr = new WebSocket(Resource.BrUrl);
    IMainService _mainService;
    public Br()
    {                  
        SubscribeToEventSetup();
    }
    public void SubscribeToEventSetup()
    {
        _webSocketBr.MessageReceived += CommonGetBrMessage;   
        _webSocketBr.Open();
    }
    public void CommonGetBrMessage(object sender, MessageReceivedEventArgs e)
    {
        Regex regexFunction = new Regex("\"msg_type\":\"[a-z_]+\"");
        switch (regexFunction.Matches(e.Message).Count != 0 ? regexFunction.Matches(e.Message)[0].Value : string.Empty)
        {
            case "\"msg_type\":\"authorize\"":
            BrAuthorize(e.Message);
            break;                  
        }
    }
    public void AuthorisationUser(string token)
    {
       AuthorizeRqt AuthorizeLogin = new AuthorizeRqt
       {
            authorize = token
       };
       _webSocketBr.Send(JsonConvert.SerializeObject(AuthorizeLogin));
    }
    private void BrAuthorize(string message)
    {
        //Вот здесь мне надо передать message в Presenter
    }
}

UPD EVENT

MainView

        public event EventHandler LoginBrClickEventRaised;
        private void ButtonBrLogin_Click(object sender, EventArgs e)
        {
            EventHelpers.RaiseEvent(this, LoginBrClickEventRaised, e);
        }

event EventHandler LoginBrClickEventRaised; в IMainView

и сам хелпер для событий

 public static class EventHelpers
{
    public static void RaiseEvent(object objectRaisingEvent, 
                                  EventHandler eventHandlerRaised, 
                                  EventArgs eventArgs)
    {
        eventHandlerRaised?.Invoke(objectRaisingEvent, eventArgs);
    }
}
Answer 1

Определимся с сообщением, что будем передавать снизу вверх

public class InfraEventArgs : EventArgs
{
    public String Message {get;}
    public InfraEventArgs(String message)
    {       
        Message = message;
    }
}

Сервис внизу, допустим, просто будет сдать сообщение каждую секунду

public class Infra
{
    public event EventHandler<InfraEventArgs> MessageHandler;
    private void Invoke(string message) => MessageHandler?.Invoke(this, new InfraEventArgs(message));
    System.Threading.Timer _timer ;
    private void Callback(object state) => Invoke($"Message with payload {Guid.NewGuid()}");
    public Infra()
    {
        _timer = new Timer(Callback, null, 0, Timeout.Infinite);
    }
    public void Start() {_timer.Change(0, 1000);}
    public void Stop() {_timer.Change(0, Timeout.Infinite);}
}

Презентер подписывается на сообщения, запускает сервис и пишет сообщения в консоль

public class Presenter
{
    private Infra _infra;
    public Presenter(Infra infra)
    {   
        _infra = infra;     
    }
    public void Start() 
    {   
        _infra.MessageHandler+=InfraMessageRecieved;
        _infra.Start();
    }
    public void Stop()
    {       
        _infra.Stop();
        _infra.MessageHandler-=InfraMessageRecieved;
    }
    private void InfraMessageRecieved(object sender, InfraEventArgs args) 
    {
        Console.WriteLine(args.Message);
    }
}

Запускается это все вот так

var infra = new Infra();
var presenter = new Presenter(infra);
presenter.Start();  
Console.ReadLine();
presenter.Stop();

Вывод в консоль происходит, значит, сообщение снизу доезжает до презентера

Message with payload 54a39438-c913-4875-b2a0-620d0bc7922b
Message with payload 8b603f62-c9ba-4eaf-952a-09491e548b75
Message with payload a587fee0-2487-4de1-9071-a15dfade70f1
Message with payload 05770d5c-e8bc-4747-9c48-a255b6180111
Message with payload f6462a41-83e1-4fd2-943a-c71961ad8050
Message with payload 22c2c132-9959-4d83-972f-f7588948470d
Message with payload ac145f74-afe3-4426-8a04-53176d4d89b1
Message with payload f73f1648-c3dc-42aa-8642-5a5b10663595
Message with payload 1fef5193-1532-4e2a-b285-38e1b8c6dd80
READ ALSO
Многопоточность с RestSharp

Многопоточность с RestSharp

Существует такая либа как RestSharp, для отправки REST запросов на сервер, мне нужно реализовать одновременную отправку на сервер несколько запросов...

171
использую selected upload для хранения картинок

использую selected upload для хранения картинок

После того как установил плагин картинки на сайте перестали отображатьсяХотя ссылки все рабочие

150
php - доступ к вложенным элементам массива

php - доступ к вложенным элементам массива

Есть многомерный массив

147