GithubHelp home page GithubHelp logo

mayuanyang / mediator.net Goto Github PK

View Code? Open in Web Editor NEW
363.0 21.0 50.0 1.01 MB

A simple mediator for .Net for sending command, publishing event and request response with pipelines supported

License: Apache License 2.0

C# 99.71% PowerShell 0.29%
mediator bus cqrs ddd csharp dotnet dotnetcore

mediator.net's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mediator.net's Issues

calling an async method in Request handler crashes the bus

Consider the following code:

 public async Task<TResponse> Handle(ReceiveContext<TRequest> context, CancellationToken token)
        {
            var request = context.Message as TRequest;
            var response = Activator.CreateInstance<TResponse>();

            Raise<NullReferenceException>.If(response == null, $"Could not create an instance of {typeof(TResponse).Name}");

            if (request.IsQueryValid(token, out var errors))
            {
                if (_cnn.State != ConnectionState.Open)
                    _cnn.Open();

                Builder.ApplyLimitingAndSorting(request);
                await Inquire(request, response, token);
                
                if (_cnn?.State == ConnectionState.Open)
                {
                    _cnn.Close();
                    _cnn.Dispose();
                }
            }
            else
                Raise<ApplicationException>.If(true, string.Join(", ", errors.Select(x => x.ErrorMessage)));

            return response;
        }

It crashes the mediator with the following error:
14-Mar-2019 16:21:23.35||ERROR|System.NullReferenceException: Object reference not set to an instance of an object.
at Mediator.Net.Pipeline.EmptyPipeSpecification1.OnException(Exception ex, TContext context) at Mediator.Net.Pipeline.GlobalReceivePipe1.Connect(TContext context, CancellationToken cancellationToken)
at Mediator.Net.Mediator.SendMessage[TMessage](TMessage msg, CancellationToken cancellationToken)
at Mediator.Net.Mediator.RequestAsync[TRequest,TResponse](TRequest request, CancellationToken cancellationToken)

However when I make changes like this:

public Task<TResponse> Handle(ReceiveContext<TRequest> context, CancellationToken token)
        {
            var request = context.Message as TRequest;
            var response = Activator.CreateInstance<TResponse>();

            Raise<NullReferenceException>.If(response == null, $"Could not create an instance of {typeof(TResponse).Name}");

            if (request.IsQueryValid(token, out var errors))
            {
                if (_cnn.State != ConnectionState.Open)
                    _cnn.Open();

                Builder.ApplyLimitingAndSorting(request);
                Inquire(request, response, token).GetAwaiter();
                
                if (_cnn?.State == ConnectionState.Open)
                {
                    _cnn.Close();
                    _cnn.Dispose();
                }
            }
            else
                Raise<ApplicationException>.If(true, string.Join(", ", errors.Select(x => x.ErrorMessage)));

            return Task.FromResult(response);
        }

it runs perfectly fine.
Aren't we supposed to call async methods ?

IPipeSpecification AfterExecute能否支持修改TContext的Result的实体


xxxcontroller.cs:

await mediator.RequestAsync<ShouldUnifyResponseCommand, UnifyResponse>(new ShouldUnifyResponseCommand());

xxxSpecification.cs:
public class xxxSpecification : IPipeSpecification
{
public Task AfterExecute(TContext context, CancellationToken cancellationToken)
{
var data = context.Result;
var unifiedTypeInstance = (Messages.Global.UnifyResponse)Activator.CreateInstance(typeof(Messages.Global.UnifyResponse));
unifiedTypeInstance.Data = data;
}
}

ShouldUnifyResponseCommandHandler.cs:
public class ShouldUnifyResponseCommandHandler : ICommandHandler<ShouldUnifyResponseCommand, ShouldUnifyResponse>
{
private readonly ITestService _service;

public ShouldUnifyResponseCommandHandler(ITestService service)
{
    _service = service;
}

public async Task<ShouldUnifyResponse> Handle(IReceiveContext<ShouldUnifyResponseCommand> context,
    CancellationToken cancellationToken)
{
    return await _service.ShouldUnifyResponse(context.Message);
}

}


如上 Handler使用的ShouldUnifyResponse , 最后通过pipe返回UnifyResponse

Few questions about Mediator.NET

Hi Again,

I'm using your mediator in two projects which are live and so far it has performed well. both the projects are web based. So kudos to you on a very clean and smooth implementation of CQRS.

I'm planning to use it in a much larger system but have a few questions which are not clear to me.

  1. What is the limit of handlers if any? In the system I'm estimating it to cross well over 800. In the projects that I have used it the number has reached to 270 max and so far no issues.

  2. Can we have a dedicated thread pool for the handlers? off course that requires a custom scheduler. I'm thinking of assigning priorities to the commands, queries and with dedicated threads based on priorities of the handlers?

  3. When delving into the code for SimpleInjector.Mediator I noticed that mediator is registered as scoped. As dotnet core apps are mostly long running apps. I'm not clear if it makes sense to register the mediator instance as scoped, isn't it better to have it as singleton?

thanks in advance

Request response result can be handled by middleware

we added the ability for SendAsync<MyCommand, MyResponse> be able to handle result in middleware, a common usage is to UnifyResponse before we send it back to the client

We need the same ability in RequestAsync<MyRequest, MyResponse>

async/await broken in ASP.NET projects

I'm using Mediator.Net with Autofac in an ASP.NET WebApi2 project. I've found out the IRequestHandler is not working properly when it's an async method with awaits.

I was able to reproduce the issue on a blank new WebApi project with the following code:

    public class DefaultController : ApiController
    {
        private readonly IMediator m;
        public DefaultController(IMediator m) => this.m = m;

        [Route("ping"), HttpGet]
        public async Task<IHttpActionResult> Ping() 
            => Ok(await m.RequestAsync<Ping, Pong>(new Ping()));

        [Route("hang"), HttpGet]
        public async Task<IHttpActionResult> Ping2()
            => Ok(await m.RequestAsync<Ping2, Pong2>(new Ping2()));
    }

    public class Ping : IRequest { }
    public class Ping2 : IRequest { }
    public class Pong : IResponse { }
    public class Pong2 : IResponse { }

    public class WorkingHandler : IRequestHandler<Ping, Pong>
    {
        public Task<Pong> Handle(ReceiveContext<Ping> context)
        {
            return Task.FromResult(new Pong());
        }
    }

    public class BrokenHandler : IRequestHandler<Ping2, Pong2>
    {
        public async Task<Pong2> Handle(ReceiveContext<Ping2> context)
        {
            await Task.Yield(); // Or whatever awaitable
            return new Pong2(); // Never reached
        }
    }

The Configuration is as folllows:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            var b = new ContainerBuilder();
            b.RegisterApiControllers(Assembly.GetExecutingAssembly());
            b.RegisterMediator(new MediatorBuilder().RegisterHandlers(Assembly.GetExecutingAssembly()));
            var c = b.Build();

            config.DependencyResolver = new AutofacWebApiDependencyResolver(c);
        }
    }

The /ping endpoint works as expected. The /hang endpoint never terminates.

I was not able to reproduce the issue in unit tests. It only happens in ASP.NET.

My first guess is that it's a deadlock caused by a blocking call of Result in RequestPipe.cs which interfered with the way IIS is handling tasks.

dll nuget not signet

I would like to be able to use the dll but since my project is signed when compiling it gives an error publickeytoken = null.

Would it be possible?

Thanks!!

Registering handlers that handles multiple messages

Hi,

I tried to register a command handler that implements multiple ICommandHandlers, then to discover that only the first ICommand was binded to the Handler. I saw your implementation in MediatorBuilder.RegisterHandlers(...) and it explicitly binds just the first interface.

Is that by design? I mean, is there any problem having Handlers with multiple ICommandHandler implementations? And finally, if there's not, do you consider allowing it?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.