Request scoped temporary store of ASP.NET Core MVC for passing data from event to view?

Viewed 26

I am working on an ASP.NET Core MVC web app.

I have a domain object method which calls a method of a 3rd party library. If something is wrong with the execution of the method, a callback function will be called.

My purpose is to pass the result of the callback function to a service which passes variables to the controller and view. I implemented it with 2 approaches.

Approach 1: temporarily store the result in a member variable of custom event handler

Approach 2: temporarily store the result in .NET Core HttpContext.Items.

Both worked but the app became super slow with Approach 2; HttpContext seems to be overkill for this.

Did I misuse HttpContext in approach 2?

Approach 1 looks like Javascript styled event handlers which have public member variables. So far I didn't see any performance issue with it. Any cons you see in approach 1?

Any suggestion of other approach?

This is roughly how I did it.

Approach 1

Class ServiceA:

private IEventBus _eventBus;
private MyEventHandler _eventHandler;

public ServiceA(IEventBus eventBus, MyEventHandler eventHandler)
{
    _eventBus = eventBus;
    _eventHandler = eventHandler;
}

public MyDTO DoSthA(string arg)
{
    DomainA domainObj = new DomainA(_eventBus);
    domainObj.doSth(arg);

    MyDTO ret = new MyDTO();
    ret.EventResult = _eventHandler.Result;

    return ret;
}

Class DomainA

private readonly IEventBus _eventBus;
private readonly Some3rdPartyStuff _some3rdPartyStuff;

public DomainA(IEventBus eventBus)
{
     _eventBus = eventBus;
     _some3rdPartyStuff = new Some3rdPartyStuff();
     
     // configuration of the 3rd party library object
     _some3rdPartyStuff.OnSomeEvent(
           var event = new MyEvent();

           // setting event member variables

           _eventBus.Dispatch(event);
     )
}    

public void DoSth(string arg) 
{
    _some3rdPartyStuff.doSth(arg);
}

Event Bus (singleton scoped)

public interface IEventBus
{
    void Dispatch<TEvent>(TEvent @event) where TEvent : IEvent;
}

public class MyEventBus : IEventBus
{
    public void Dispatch<TEvent>(TEvent @event) where TEvent : IEvent 
    {
        if (@event == null) 
            throw new ArgumentNullException("event");

        var handlerType = typeof(IEventHandler<>).MakeGenericType(@event.GetType());
        dynamic handlers = DIContainer.INSTANCE.GetAllInstances<IEventHandler<TEvent>>();

        foreach (var handler in handlers) 
        {
            handler.Handle(@event);
        }
}

Ref: Implementing Domain Event Handler pattern in C# with Simple Injector

Event Handler (Request scoped)

public interface IEventHandler<TEvent>
{
    void Handle(TEvent @event);
}

public class MyEventHandler : IEventHandler<MyEvent>
{
    public EventResult Result { get; private set; }

    public void Handle(MyEvent @event) {

        var result = new EventResult();
        // setting variables of EventResult 
        Result = result;
    }
}

Approach 2

Class ServiceA

private IEventBus _eventBus;
private IHttpContextAccessor _httpContextAccessor;

public ServiceA(IEventBus eventBus, IHttpContextAccessor httpContextAccessor){

    _eventBus = eventBus;
     _httpContextAccessor = httpContextAccessor;
}

public MyDTO DoSthA(string arg){

    DomainA domainObj = new DomainA(_eventBus);
    domainObj.doSth(arg);

    bool eventHandled = _httpContextAccessor.HttpContext.Items.Contins("key");


    MyDTO ret = new MyDTO();
    ret.EventResult = eventHandled ? _httpContextAccessor.HttpContext.Items[”key”] : new MyEventResult(); // default result value

    return ret;
}

Event Handler (Request scoped)

public interface IEventHandler<TEvent>
{
    void Handle(TEvent @event);
}

public class MyEventHandler : IEventHandler<MyEvent>
{
    public MyEventHandler(IHttpContextAccessor httpContextAccessor){
        _httpContextAccessor = httpContextAccessor;
    }

    public void Handle(MyEvent @event) {

        var result = new EventResult();
        // setting variables of EventResult 
        _httpContextAccessor.HttpContext.Items["key"]= result;
    }
}
0 Answers
Related